Selaa lähdekoodia

cms支持多系统

shuzheng 8 vuotta sitten
vanhempi
commit
5637af213f
35 muutettua tiedostoa jossa 1426 lisäystä ja 310 poistoa
  1. 14 0
      zheng-cms/zheng-cms-rpc-api/src/main/java/com/zheng/cms/rpc/api/CmsArticleService.java
  2. 30 0
      zheng-cms/zheng-cms-rpc-api/src/main/java/com/zheng/cms/rpc/api/CmsArticleServiceMock.java
  3. 26 0
      zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsArticleExtMapper.java
  4. 74 0
      zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsArticleExtMapper.xml
  5. 0 13
      zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsArticleVOMapper.java
  6. 0 23
      zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsArticleVOMapper.xml
  7. 1 1
      zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsCategoryExtMapper.java
  8. 1 1
      zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsTagExtMapper.java
  9. 26 0
      zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/service/impl/CmsArticleServiceImpl.java
  10. 0 51
      zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/ArticleController.java
  11. 151 1
      zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/BlogController.java
  12. 0 70
      zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/CategoryController.java
  13. 6 25
      zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/IndexController.java
  14. 151 1
      zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/NewsController.java
  15. 151 1
      zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/QaController.java
  16. 0 73
      zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/TagController.java
  17. 109 0
      zheng-ui/zheng-cms-web/blog/category/index.html
  18. 9 9
      zheng-ui/zheng-cms-web/blog/details/index.html
  19. 14 2
      zheng-ui/zheng-cms-web/blog/index.html
  20. 109 0
      zheng-ui/zheng-cms-web/blog/tag/index.html
  21. 6 14
      zheng-ui/zheng-cms-web/index.html
  22. 125 0
      zheng-ui/zheng-cms-web/news/article/index.html
  23. 10 10
      zheng-ui/zheng-cms-web/news/category/index.html
  24. 13 1
      zheng-ui/zheng-cms-web/news/index.html
  25. 10 10
      zheng-ui/zheng-cms-web/news/tag/index.html
  26. 109 0
      zheng-ui/zheng-cms-web/qa/category/index.html
  27. 13 1
      zheng-ui/zheng-cms-web/qa/index.html
  28. 125 0
      zheng-ui/zheng-cms-web/qa/question/index.html
  29. 109 0
      zheng-ui/zheng-cms-web/qa/tag/index.html
  30. 1 1
      zheng-ui/zheng-cms-web/search/index.html
  31. 1 0
      zheng-upms/zheng-upms-rpc-api/src/main/java/com/zheng/upms/rpc/api/UpmsUserService.java
  32. 4 0
      zheng-upms/zheng-upms-rpc-api/src/main/java/com/zheng/upms/rpc/api/UpmsUserServiceMock.java
  33. 5 0
      zheng-upms/zheng-upms-rpc-service/src/main/java/com/zheng/upms/rpc/service/impl/UpmsUserServiceImpl.java
  34. 22 2
      zheng-upms/zheng-upms-rpc-service/src/test/java/com/zheng/upms/rpc/service/UpmsServiceTest.java
  35. 1 0
      zheng-upms/zheng-upms-server/src/main/java/com/zheng/upms/server/controller/manage/UpmsUserController.java

+ 14 - 0
zheng-cms/zheng-cms-rpc-api/src/main/java/com/zheng/cms/rpc/api/CmsArticleService.java

@@ -4,10 +4,24 @@ import com.zheng.common.base.BaseService;
 import com.zheng.cms.dao.model.CmsArticle;
 import com.zheng.cms.dao.model.CmsArticleExample;
 
+import java.util.List;
+
 /**
 * CmsArticleService接口
 * Created by shuzheng on 2017/4/5.
 */
 public interface CmsArticleService extends BaseService<CmsArticle, CmsArticleExample> {
 
+    // 根据类目获取文章列表
+    List<CmsArticle> selectCmsArticlesByCategoryId(Integer categoryId, Integer offset, Integer limit);
+
+    // 根据类目获取文章数量
+    long countByCategoryId(Integer categoryId);
+
+    // 根据标签获取文章列表
+    List<CmsArticle> selectCmsArticlesByTagId(Integer tagId, Integer offset, Integer limit);
+
+    // 根据标签获取文章数量
+    long countByTagId(Integer tagId);
+
 }

+ 30 - 0
zheng-cms/zheng-cms-rpc-api/src/main/java/com/zheng/cms/rpc/api/CmsArticleServiceMock.java

@@ -4,6 +4,10 @@ import com.zheng.common.base.BaseServiceMock;
 import com.zheng.cms.dao.mapper.CmsArticleMapper;
 import com.zheng.cms.dao.model.CmsArticle;
 import com.zheng.cms.dao.model.CmsArticleExample;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
 
 /**
 * 降级实现CmsArticleService接口
@@ -11,4 +15,30 @@ import com.zheng.cms.dao.model.CmsArticleExample;
 */
 public class CmsArticleServiceMock extends BaseServiceMock<CmsArticleMapper, CmsArticle, CmsArticleExample> implements CmsArticleService {
 
+    private static Logger _log = LoggerFactory.getLogger(CmsArticleServiceMock.class);
+
+    @Override
+    public List<CmsArticle> selectCmsArticlesByCategoryId(Integer categoryId, Integer offset, Integer limit) {
+        _log.info("CmsArticleServiceMock => getCmsArticlesByCategoryId");
+        return null;
+    }
+
+    @Override
+    public long countByCategoryId(Integer categoryId) {
+        _log.info("CmsArticleServiceMock => countByCategoryId");
+        return 0;
+    }
+
+    @Override
+    public List<CmsArticle> selectCmsArticlesByTagId(Integer tagId, Integer offset, Integer limit) {
+        _log.info("CmsArticleServiceMock => getCmsArticlesByCategoryId");
+        return null;
+    }
+
+    @Override
+    public long countByTagId(Integer tagId) {
+        _log.info("CmsArticleServiceMock => countByTagId");
+        return 0;
+    }
+
 }

+ 26 - 0
zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsArticleExtMapper.java

@@ -0,0 +1,26 @@
+package com.zheng.cms.rpc.mapper;
+
+import com.zheng.cms.dao.model.CmsArticle;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 文章VOMapper
+ * Created by shuzheng on 2017/01/07.
+ */
+public interface CmsArticleExtMapper {
+
+    int up(Integer articleId);
+
+    int down(Integer articleId);
+
+    List<CmsArticle> selectCmsArticlesByCategoryId(@Param("categoryId") Integer categoryId, @Param("offset") Integer offset, @Param("limit") Integer limit);
+
+    long countByCategoryId(@Param("categoryId") Integer categoryId);
+
+    List<CmsArticle> selectCmsArticlesByTagId(@Param("tagId") Integer tagId, @Param("offset") Integer offset, @Param("limit") Integer limit);
+
+    long countByTagId(@Param("tagId") Integer tagId);
+
+}

+ 74 - 0
zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsArticleExtMapper.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zheng.cms.rpc.mapper.CmsArticleExtMapper">
+
+	<resultMap id="BaseResultMap" type="com.zheng.cms.dao.model.CmsArticle">
+		<id column="article_id" jdbcType="INTEGER" property="articleId" />
+		<result column="topic_id" jdbcType="INTEGER" property="topicId" />
+		<result column="title" jdbcType="VARCHAR" property="title" />
+		<result column="author" jdbcType="VARCHAR" property="author" />
+		<result column="fromurl" jdbcType="VARCHAR" property="fromurl" />
+		<result column="image" jdbcType="VARCHAR" property="image" />
+		<result column="keywords" jdbcType="VARCHAR" property="keywords" />
+		<result column="description" jdbcType="VARCHAR" property="description" />
+		<result column="type" jdbcType="TINYINT" property="type" />
+		<result column="allowcomments" jdbcType="TINYINT" property="allowcomments" />
+		<result column="status" jdbcType="TINYINT" property="status" />
+		<result column="user_id" jdbcType="INTEGER" property="userId" />
+		<result column="readnumber" jdbcType="INTEGER" property="readnumber" />
+		<result column="top" jdbcType="INTEGER" property="top" />
+		<result column="system_id" jdbcType="INTEGER" property="systemId" />
+		<result column="ctime" jdbcType="BIGINT" property="ctime" />
+		<result column="orders" jdbcType="BIGINT" property="orders" />
+	</resultMap>
+	<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.zheng.cms.dao.model.CmsArticle">
+		<result column="content" jdbcType="LONGVARCHAR" property="content" />
+	</resultMap>
+
+	<!-- 排序上移 -->
+	<select id="up" resultType="java.lang.Integer" parameterType="java.lang.Integer">
+		select
+			u.id u_id,u.username,u.password,u.nickname,u.sex,u.ctime,u.content,
+			b.id b_id,b.userid,b.name
+		from
+			cms_user u
+		left join
+			cms_book b
+		on
+			u.id=b.userid
+		where
+			u.id=#{id,jdbcType=INTEGER}
+	</select>
+
+	<!-- 根据类目获取文章列表 -->
+	<select id="selectCmsArticlesByCategoryId" resultMap="ResultMapWithBLOBs" parameterType="map">
+		select ca.* from cms_article_category cac left join cms_article ca on cac.article_id=ca.article_id join (
+			select article_id from cms_article order by article_id desc
+		) ca_order on ca_order.article_id=ca.article_id where ca.status=1 and cac.category_id=#{categoryId,jdbcType=INTEGER} limit #{offset,jdbcType=INTEGER}, #{limit,jdbcType=INTEGER}
+	</select>
+
+	<!-- 根据类目获取文章数量 -->
+	<select id="countByCategoryId" resultType="java.lang.Long" parameterType="map">
+		select count(*) from cms_article_category cac left join cms_article ca on cac.article_id=ca.article_id join (
+		    select article_id from cms_article order by article_id desc
+		) ca_order on ca_order.article_id=ca.article_id where ca.status=1 and cac.category_id=#{categoryId,jdbcType=INTEGER}
+	</select>
+
+	<!-- 根据标签获取文章列表 -->
+	<select id="selectCmsArticlesByTagId" resultMap="ResultMapWithBLOBs" parameterType="map">
+		select ca.* from cms_article_tag cat left join cms_article ca on cat.article_id=ca.article_id join (
+			select article_id from cms_article order by article_id desc
+		) ca_order on ca_order.article_id=ca.article_id where ca.status=1 and cat.tag_id=#{tagId,jdbcType=INTEGER} limit #{offset,jdbcType=INTEGER}, #{limit,jdbcType=INTEGER}
+	</select>
+
+	<!-- 根据标签获取文章数量 -->
+	<select id="countByTagId" resultType="java.lang.Long" parameterType="map">
+		select count(*) from cms_article_tag cat left join cms_article ca on cat.article_id=ca.article_id join (
+			select article_id from cms_article order by article_id desc
+		) ca_order on ca_order.article_id=ca.article_id where ca.status=1 and cat.tag_id=#{tagId,jdbcType=INTEGER}
+	</select>
+
+	<!-- 缓存 -->
+	<cache type="org.mybatis.caches.ehcache.LoggingEhcache" />
+
+</mapper>

+ 0 - 13
zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsArticleVOMapper.java

@@ -1,13 +0,0 @@
-package com.zheng.cms.rpc.mapper;
-
-/**
- * 文章VOMapper
- * Created by shuzheng on 2017/01/07.
- */
-public interface CmsArticleVOMapper {
-
-    int up(Integer articleId);
-
-    int down(Integer articleId);
-
-}

+ 0 - 23
zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsArticleVOMapper.xml

@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.zheng.cms.rpc.mapper.CmsArticleVOMapper">
-
-	<!-- 排序上移 -->
-	<select id="up" resultType="int" parameterType="int">
-		select
-			u.id u_id,u.username,u.password,u.nickname,u.sex,u.ctime,u.content,
-			b.id b_id,b.userid,b.name
-		from
-			cms_user u
-		left join
-			cms_book b
-		on
-			u.id=b.userid
-		where
-			u.id=#{id,jdbcType=INTEGER}
-	</select>
-
-	<!-- 缓存 -->
-	<cache type="org.mybatis.caches.ehcache.LoggingEhcache" />
-
-</mapper>

+ 1 - 1
zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsCategoryVOMapper.java → zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsCategoryExtMapper.java

@@ -4,7 +4,7 @@ package com.zheng.cms.rpc.mapper;
  * 类目VOMapper
  * Created by shuzheng on 2017/01/07.
  */
-public interface CmsCategoryVOMapper {
+public interface CmsCategoryExtMapper {
 
     int up(Integer articleId);
 

+ 1 - 1
zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsTagVOMapper.java → zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/mapper/CmsTagExtMapper.java

@@ -4,7 +4,7 @@ package com.zheng.cms.rpc.mapper;
  * 标签VOMapper
  * Created by shuzheng on 2017/01/07.
  */
-public interface CmsTagVOMapper {
+public interface CmsTagExtMapper {
 
     int up(Integer articleId);
 

+ 26 - 0
zheng-cms/zheng-cms-rpc-service/src/main/java/com/zheng/cms/rpc/service/impl/CmsArticleServiceImpl.java

@@ -1,5 +1,6 @@
 package com.zheng.cms.rpc.service.impl;
 
+import com.zheng.cms.rpc.mapper.CmsArticleExtMapper;
 import com.zheng.common.annotation.BaseService;
 import com.zheng.common.base.BaseServiceImpl;
 import com.zheng.cms.dao.mapper.CmsArticleMapper;
@@ -12,6 +13,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.List;
+
 /**
 * CmsArticleService实现
 * Created by shuzheng on 2017/4/5.
@@ -26,4 +29,27 @@ public class CmsArticleServiceImpl extends BaseServiceImpl<CmsArticleMapper, Cms
     @Autowired
     CmsArticleMapper cmsArticleMapper;
 
+    @Autowired
+    CmsArticleExtMapper cmsArticleExtMapper;
+
+    @Override
+    public List<CmsArticle> selectCmsArticlesByCategoryId(Integer categoryId, Integer offset, Integer limit) {
+        return cmsArticleExtMapper.selectCmsArticlesByCategoryId(categoryId, offset, limit);
+    }
+
+    @Override
+    public long countByCategoryId(Integer categoryId) {
+        return cmsArticleExtMapper.countByCategoryId(categoryId);
+    }
+
+    @Override
+    public List<CmsArticle> selectCmsArticlesByTagId(Integer tagId, Integer offset, Integer limit) {
+        return cmsArticleExtMapper.selectCmsArticlesByTagId(tagId, offset, limit);
+    }
+
+    @Override
+    public long countByTagId(Integer tagId) {
+        return cmsArticleExtMapper.countByTagId(tagId);
+    }
+
 }

+ 0 - 51
zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/ArticleController.java

@@ -1,51 +0,0 @@
-package com.zheng.cms.web.controller;
-
-import com.zheng.cms.dao.model.CmsArticle;
-import com.zheng.cms.dao.model.CmsComment;
-import com.zheng.cms.dao.model.CmsCommentExample;
-import com.zheng.cms.rpc.api.CmsArticleService;
-import com.zheng.cms.rpc.api.CmsCommentService;
-import com.zheng.common.base.BaseController;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-import java.util.List;
-
-/**
- * 文章控制器
- * Created by shuzheng on 2017/3/26.
- */
-@Controller
-@RequestMapping(value = "/article")
-public class ArticleController extends BaseController {
-
-    private static Logger _log = LoggerFactory.getLogger(ArticleController.class);
-
-    @Autowired
-    private CmsArticleService cmsArticleService;
-
-    @Autowired
-    private CmsCommentService cmsCommentService;
-
-    @RequestMapping(value = "/{articleId}", method = RequestMethod.GET)
-    public String index(@PathVariable("articleId") int articleId, Model model) {
-        CmsArticle article = cmsArticleService.selectByPrimaryKey(articleId);
-        model.addAttribute("article", article);
-        // 评论列表
-        CmsCommentExample cmsCommentExample = new CmsCommentExample();
-        cmsCommentExample.createCriteria()
-                .andArticleIdEqualTo(articleId)
-                .andStatusEqualTo((byte) 1);
-        cmsCommentExample.setOrderByClause("ctime desc");
-        List<CmsComment> comments = cmsCommentService.selectByExampleWithBLOBs(cmsCommentExample);
-        model.addAttribute("comments", comments);
-        return thymeleaf("/article/index");
-    }
-
-}

+ 151 - 1
zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/BlogController.java

@@ -1,12 +1,22 @@
 package com.zheng.cms.web.controller;
 
+import com.zheng.cms.dao.model.*;
+import com.zheng.cms.rpc.api.*;
 import com.zheng.common.base.BaseController;
+import com.zheng.common.util.Paginator;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 /**
  * 博客首页控制器
@@ -17,10 +27,150 @@ import org.springframework.web.bind.annotation.RequestMethod;
 public class BlogController extends BaseController {
 
     private static Logger _log = LoggerFactory.getLogger(BlogController.class);
+    private static String CODE = "blog";
+
+    @Autowired
+    private CmsArticleService cmsArticleService;
+
+    @Autowired
+    private CmsCategoryService cmsCategoryService;
+
+    @Autowired
+    private CmsTagService cmsTagService;
+
+    @Autowired
+    private CmsSystemService cmsSystemService;
+
+    @Autowired
+    private CmsCommentService cmsCommentService;
 
     @RequestMapping(value = "", method = RequestMethod.GET)
-    public String index(Model model) {
+    public String index(@RequestParam(required = false, defaultValue = "1", value = "page") int page,
+                        @RequestParam(required = false, defaultValue = "orders", value = "sort") String sort,
+                        @RequestParam(required = false, defaultValue = "desc", value = "order") String order,
+                        HttpServletRequest request,
+                        Model model) {
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 该系统类目
+        CmsCategoryExample cmsCategoryExample = new CmsCategoryExample();
+        cmsCategoryExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId());
+        cmsCategoryExample.setOrderByClause("orders asc");
+        List<CmsCategory> categories = cmsCategoryService.selectByExample(cmsCategoryExample);
+        model.addAttribute("categories", categories);
+        // 该系统标签
+        CmsTagExample cmsTagExample = new CmsTagExample();
+        cmsTagExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId());
+        cmsTagExample.setOrderByClause("orders asc");
+        List<CmsTag> tags = cmsTagService.selectByExample(cmsTagExample);
+        model.addAttribute("tags", tags);
+        // 该系统文章列表
+        int rows = 10;
+        CmsArticleExample cmsArticleExample = new CmsArticleExample();
+        cmsArticleExample.createCriteria()
+                .andStatusEqualTo((byte) 1)
+                .andSystemIdEqualTo(system.getSystemId());
+        cmsArticleExample.setOffset((page - 1) * rows);
+        cmsArticleExample.setLimit(rows);
+        if (!StringUtils.isBlank(sort) && !StringUtils.isBlank(order)) {
+            cmsArticleExample.setOrderByClause(sort + " " + order);
+        }
+        List<CmsArticle> articles = cmsArticleService.selectByExample(cmsArticleExample);
+        model.addAttribute("articles", articles);
+        // 文章总数
+        long total = cmsArticleService.countByExample(cmsArticleExample);
+        // 分页
+        Paginator paginator = new Paginator(total, page, rows, request);
+        model.addAttribute("paginator", paginator);
         return thymeleaf("/blog/index");
     }
 
+    @RequestMapping(value = "/category/{alias}", method = RequestMethod.GET)
+    public String category(@PathVariable("alias") String alias,
+                           @RequestParam(required = false, defaultValue = "1", value = "page") int page,
+                           HttpServletRequest request,
+                           Model model) {
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 当前类目
+        CmsCategoryExample cmsCategoryExample = new CmsCategoryExample();
+        cmsCategoryExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId())
+                .andAliasEqualTo(alias);
+        CmsCategory category = cmsCategoryService.selectFirstByExample(cmsCategoryExample);
+        model.addAttribute("category", category);
+        // 该类目文章列表
+        int rows = 10;
+        List<CmsArticle> articles = cmsArticleService.selectCmsArticlesByCategoryId(category.getCategoryId(), (page - 1) * rows, rows);
+        model.addAttribute("articles", articles);
+        // 文章总数
+        long total = cmsArticleService.countByCategoryId(category.getCategoryId());
+        // 分页
+        Paginator paginator = new Paginator(total, page, rows, request);
+        model.addAttribute("paginator", paginator);
+        return thymeleaf("/blog/category/index");
+    }
+
+    @RequestMapping(value = "/tag/{alias}", method = RequestMethod.GET)
+    public String tag(@PathVariable("alias") String alias,
+                      @RequestParam(required = false, defaultValue = "1", value = "page") int page,
+                      HttpServletRequest request,
+                      Model model) {
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 当前标签
+        CmsTagExample cmsTagExample = new CmsTagExample();
+        cmsTagExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId())
+                .andAliasEqualTo(alias);
+        CmsTag tag = cmsTagService.selectFirstByExample(cmsTagExample);
+        model.addAttribute("tag", tag);
+        // 该标签文章列表
+        int rows = 10;
+        List<CmsArticle> articles = cmsArticleService.selectCmsArticlesByTagId(tag.getTagId(), (page - 1) * rows, rows);
+        model.addAttribute("articles", articles);
+        // 文章总数
+        long total = cmsArticleService.countByTagId(tag.getTagId());
+        // 分页
+        Paginator paginator = new Paginator(total, page, rows, request);
+        model.addAttribute("paginator", paginator);
+        return thymeleaf("/blog/tag/index");
+    }
+
+    @RequestMapping(value = "/details/{articleId}", method = RequestMethod.GET)
+    public String details(@PathVariable("articleId") int articleId, Model model) {
+        CmsArticle article = cmsArticleService.selectByPrimaryKey(articleId);
+        model.addAttribute("article", article);
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 评论列表
+        CmsCommentExample cmsCommentExample = new CmsCommentExample();
+        cmsCommentExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId())
+                .andArticleIdEqualTo(articleId)
+                .andStatusEqualTo((byte) 1);
+        cmsCommentExample.setOrderByClause("ctime desc");
+        List<CmsComment> comments = cmsCommentService.selectByExampleWithBLOBs(cmsCommentExample);
+        model.addAttribute("comments", comments);
+        return thymeleaf("/blog/details/index");
+    }
+
 }

+ 0 - 70
zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/CategoryController.java

@@ -1,70 +0,0 @@
-package com.zheng.cms.web.controller;
-
-import com.zheng.cms.dao.model.*;
-import com.zheng.cms.rpc.api.*;
-import com.zheng.common.base.BaseController;
-import com.zheng.common.util.Paginator;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.List;
-
-/**
- * 类目控制器
- * Created by shuzheng on 2017/3/26.
- */
-@Controller
-@RequestMapping(value = "/category")
-public class CategoryController extends BaseController {
-
-	private static Logger _log = LoggerFactory.getLogger(CategoryController.class);
-
-	@Autowired
-	private CmsCategoryService cmsCategoryService;
-
-	@Autowired
-	private CmsArticleService cmsArticleService;
-
-	@RequestMapping(value = "/{alias}", method = RequestMethod.GET)
-	public String index(@PathVariable("alias") String alias,
-						@RequestParam(required = false, defaultValue = "1", value = "page") int page,
-						@RequestParam(required = false, defaultValue = "orders", value = "sort") String sort,
-						@RequestParam(required = false, defaultValue = "desc", value = "order") String order,
-						HttpServletRequest request,
-						Model model) {
-		// 当前类目
-		CmsCategoryExample cmsCategoryExample = new CmsCategoryExample();
-		cmsCategoryExample.createCriteria()
-				.andAliasEqualTo(alias);
-		CmsCategory category = cmsCategoryService.selectFirstByExample(cmsCategoryExample);
-		model.addAttribute("category", category);
-		// 该类目文章列表
-		int rows = 10;
-		CmsArticleExample cmsArticleExample = new CmsArticleExample();
-		cmsArticleExample.createCriteria()
-				.andStatusEqualTo((byte) 1);
-		cmsArticleExample.setOffset((page - 1) * rows);
-		cmsArticleExample.setLimit(rows);
-		if (!StringUtils.isBlank(sort) && !StringUtils.isBlank(order)) {
-			cmsArticleExample.setOrderByClause(sort + " " + order);
-		}
-		List<CmsArticle> articles = cmsArticleService.selectByExample(cmsArticleExample);
-		model.addAttribute("articles", articles);
-		// 文章总数
-		long total = cmsArticleService.countByExample(cmsArticleExample);
-		// 分页
-		Paginator paginator = new Paginator(total, page, rows, request);
-		model.addAttribute("paginator", paginator);
-		return thymeleaf("/category/index");
-	}
-
-}

+ 6 - 25
zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/IndexController.java

@@ -32,18 +32,15 @@ public class IndexController extends BaseController {
     private CmsTagService cmsTagService;
 
     @Autowired
-    private CmsTopicService cmsTopicService;
-
-    @Autowired
-    private CmsArticleService cmsArticleService;
+    private CmsSystemService cmsSystemService;
 
     @RequestMapping(value = "", method = RequestMethod.GET)
     public String index(Model model) {
-        // 菜单
-        CmsMenuExample cmsMenuExample = new CmsMenuExample();
-        cmsMenuExample.setOrderByClause("orders asc");
-        List<CmsMenu> menus = cmsMenuService.selectByExample(cmsMenuExample);
-        model.addAttribute("menus", menus);
+        // 所有系统
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.setOrderByClause("orders asc");
+        List<CmsSystem> systems = cmsSystemService.selectByExample(cmsSystemExample);
+        model.addAttribute("systems", systems);
         // 所有类目
         CmsCategoryExample cmsCategoryExample = new CmsCategoryExample();
         cmsCategoryExample.setOrderByClause("orders asc");
@@ -54,22 +51,6 @@ public class IndexController extends BaseController {
         cmsTagExample.setOrderByClause("orders asc");
         List<CmsTag> tags = cmsTagService.selectByExample(cmsTagExample);
         model.addAttribute("tags", tags);
-        // 最新5个专题
-        CmsTopicExample cmsTopicExample = new CmsTopicExample();
-        cmsTopicExample.setOrderByClause("ctime desc");
-        List<CmsTopic> topics = cmsTopicService.selectByExample(cmsTopicExample);
-        model.addAttribute("topics", topics);
-        // 最新5条文章
-        CmsArticleExample cmsArticleExample = new CmsArticleExample();
-        cmsArticleExample.createCriteria()
-                .andStatusEqualTo((byte) 1);
-        cmsArticleExample.setOrderByClause("orders desc");
-        List<CmsArticle> newArticles = cmsArticleService.selectByExample(cmsArticleExample);
-        model.addAttribute("newArticles", newArticles);
-        // 最火5条文章
-        cmsArticleExample.setOrderByClause("readnumber desc");
-        List<CmsArticle> hotArticles = cmsArticleService.selectByExample(cmsArticleExample);
-        model.addAttribute("hotArticles", hotArticles);
         return thymeleaf("/index");
     }
 

+ 151 - 1
zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/NewsController.java

@@ -1,12 +1,22 @@
 package com.zheng.cms.web.controller;
 
+import com.zheng.cms.dao.model.*;
+import com.zheng.cms.rpc.api.*;
 import com.zheng.common.base.BaseController;
+import com.zheng.common.util.Paginator;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 /**
  * 资讯首页控制器
@@ -17,10 +27,150 @@ import org.springframework.web.bind.annotation.RequestMethod;
 public class NewsController extends BaseController {
 
     private static Logger _log = LoggerFactory.getLogger(NewsController.class);
+    private static String CODE = "news";
+
+    @Autowired
+    private CmsArticleService cmsArticleService;
+
+    @Autowired
+    private CmsCategoryService cmsCategoryService;
+
+    @Autowired
+    private CmsTagService cmsTagService;
+
+    @Autowired
+    private CmsSystemService cmsSystemService;
+
+    @Autowired
+    private CmsCommentService cmsCommentService;
 
     @RequestMapping(value = "", method = RequestMethod.GET)
-    public String index(Model model) {
+    public String index(@RequestParam(required = false, defaultValue = "1", value = "page") int page,
+                        @RequestParam(required = false, defaultValue = "orders", value = "sort") String sort,
+                        @RequestParam(required = false, defaultValue = "desc", value = "order") String order,
+                        HttpServletRequest request,
+                        Model model) {
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 该系统类目
+        CmsCategoryExample cmsCategoryExample = new CmsCategoryExample();
+        cmsCategoryExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId());
+        cmsCategoryExample.setOrderByClause("orders asc");
+        List<CmsCategory> categories = cmsCategoryService.selectByExample(cmsCategoryExample);
+        model.addAttribute("categories", categories);
+        // 该系统标签
+        CmsTagExample cmsTagExample = new CmsTagExample();
+        cmsTagExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId());
+        cmsTagExample.setOrderByClause("orders asc");
+        List<CmsTag> tags = cmsTagService.selectByExample(cmsTagExample);
+        model.addAttribute("tags", tags);
+        // 该系统文章列表
+        int rows = 10;
+        CmsArticleExample cmsArticleExample = new CmsArticleExample();
+        cmsArticleExample.createCriteria()
+                .andStatusEqualTo((byte) 1)
+                .andSystemIdEqualTo(system.getSystemId());
+        cmsArticleExample.setOffset((page - 1) * rows);
+        cmsArticleExample.setLimit(rows);
+        if (!StringUtils.isBlank(sort) && !StringUtils.isBlank(order)) {
+            cmsArticleExample.setOrderByClause(sort + " " + order);
+        }
+        List<CmsArticle> articles = cmsArticleService.selectByExample(cmsArticleExample);
+        model.addAttribute("articles", articles);
+        // 文章总数
+        long total = cmsArticleService.countByExample(cmsArticleExample);
+        // 分页
+        Paginator paginator = new Paginator(total, page, rows, request);
+        model.addAttribute("paginator", paginator);
         return thymeleaf("/news/index");
     }
 
+    @RequestMapping(value = "/category/{alias}", method = RequestMethod.GET)
+    public String category(@PathVariable("alias") String alias,
+                        @RequestParam(required = false, defaultValue = "1", value = "page") int page,
+                        HttpServletRequest request,
+                        Model model) {
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 当前类目
+        CmsCategoryExample cmsCategoryExample = new CmsCategoryExample();
+        cmsCategoryExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId())
+                .andAliasEqualTo(alias);
+        CmsCategory category = cmsCategoryService.selectFirstByExample(cmsCategoryExample);
+        model.addAttribute("category", category);
+        // 该类目文章列表
+        int rows = 10;
+        List<CmsArticle> articles = cmsArticleService.selectCmsArticlesByCategoryId(category.getCategoryId(), (page - 1) * rows, rows);
+        model.addAttribute("articles", articles);
+        // 文章总数
+        long total = cmsArticleService.countByCategoryId(category.getCategoryId());
+        // 分页
+        Paginator paginator = new Paginator(total, page, rows, request);
+        model.addAttribute("paginator", paginator);
+        return thymeleaf("/news/category/index");
+    }
+
+    @RequestMapping(value = "/tag/{alias}", method = RequestMethod.GET)
+    public String tag(@PathVariable("alias") String alias,
+                        @RequestParam(required = false, defaultValue = "1", value = "page") int page,
+                        HttpServletRequest request,
+                        Model model) {
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 当前标签
+        CmsTagExample cmsTagExample = new CmsTagExample();
+        cmsTagExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId())
+                .andAliasEqualTo(alias);
+        CmsTag tag = cmsTagService.selectFirstByExample(cmsTagExample);
+        model.addAttribute("tag", tag);
+        // 该标签文章列表
+        int rows = 10;
+        List<CmsArticle> articles = cmsArticleService.selectCmsArticlesByTagId(tag.getTagId(), (page - 1) * rows, rows);
+        model.addAttribute("articles", articles);
+        // 文章总数
+        long total = cmsArticleService.countByTagId(tag.getTagId());
+        // 分页
+        Paginator paginator = new Paginator(total, page, rows, request);
+        model.addAttribute("paginator", paginator);
+        return thymeleaf("/news/tag/index");
+    }
+
+    @RequestMapping(value = "/article/{articleId}", method = RequestMethod.GET)
+    public String article(@PathVariable("articleId") int articleId, Model model) {
+        CmsArticle article = cmsArticleService.selectByPrimaryKey(articleId);
+        model.addAttribute("article", article);
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 评论列表
+        CmsCommentExample cmsCommentExample = new CmsCommentExample();
+        cmsCommentExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId())
+                .andArticleIdEqualTo(articleId)
+                .andStatusEqualTo((byte) 1);
+        cmsCommentExample.setOrderByClause("ctime desc");
+        List<CmsComment> comments = cmsCommentService.selectByExampleWithBLOBs(cmsCommentExample);
+        model.addAttribute("comments", comments);
+        return thymeleaf("/news/article/index");
+    }
+
 }

+ 151 - 1
zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/QaController.java

@@ -1,12 +1,22 @@
 package com.zheng.cms.web.controller;
 
+import com.zheng.cms.dao.model.*;
+import com.zheng.cms.rpc.api.*;
 import com.zheng.common.base.BaseController;
+import com.zheng.common.util.Paginator;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 /**
  * 问答首页控制器
@@ -17,10 +27,150 @@ import org.springframework.web.bind.annotation.RequestMethod;
 public class QaController extends BaseController {
 
     private static Logger _log = LoggerFactory.getLogger(QaController.class);
+    private static String CODE = "qa";
+
+    @Autowired
+    private CmsArticleService cmsArticleService;
+
+    @Autowired
+    private CmsCategoryService cmsCategoryService;
+
+    @Autowired
+    private CmsTagService cmsTagService;
+
+    @Autowired
+    private CmsSystemService cmsSystemService;
+
+    @Autowired
+    private CmsCommentService cmsCommentService;
 
     @RequestMapping(value = "", method = RequestMethod.GET)
-    public String index(Model model) {
+    public String index(@RequestParam(required = false, defaultValue = "1", value = "page") int page,
+                        @RequestParam(required = false, defaultValue = "orders", value = "sort") String sort,
+                        @RequestParam(required = false, defaultValue = "desc", value = "order") String order,
+                        HttpServletRequest request,
+                        Model model) {
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 该系统类目
+        CmsCategoryExample cmsCategoryExample = new CmsCategoryExample();
+        cmsCategoryExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId());
+        cmsCategoryExample.setOrderByClause("orders asc");
+        List<CmsCategory> categories = cmsCategoryService.selectByExample(cmsCategoryExample);
+        model.addAttribute("categories", categories);
+        // 该系统标签
+        CmsTagExample cmsTagExample = new CmsTagExample();
+        cmsTagExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId());
+        cmsTagExample.setOrderByClause("orders asc");
+        List<CmsTag> tags = cmsTagService.selectByExample(cmsTagExample);
+        model.addAttribute("tags", tags);
+        // 该系统文章列表
+        int rows = 10;
+        CmsArticleExample cmsArticleExample = new CmsArticleExample();
+        cmsArticleExample.createCriteria()
+                .andStatusEqualTo((byte) 1)
+                .andSystemIdEqualTo(system.getSystemId());
+        cmsArticleExample.setOffset((page - 1) * rows);
+        cmsArticleExample.setLimit(rows);
+        if (!StringUtils.isBlank(sort) && !StringUtils.isBlank(order)) {
+            cmsArticleExample.setOrderByClause(sort + " " + order);
+        }
+        List<CmsArticle> articles = cmsArticleService.selectByExample(cmsArticleExample);
+        model.addAttribute("articles", articles);
+        // 文章总数
+        long total = cmsArticleService.countByExample(cmsArticleExample);
+        // 分页
+        Paginator paginator = new Paginator(total, page, rows, request);
+        model.addAttribute("paginator", paginator);
         return thymeleaf("/qa/index");
     }
 
+    @RequestMapping(value = "/category/{alias}", method = RequestMethod.GET)
+    public String category(@PathVariable("alias") String alias,
+                           @RequestParam(required = false, defaultValue = "1", value = "page") int page,
+                           HttpServletRequest request,
+                           Model model) {
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 当前类目
+        CmsCategoryExample cmsCategoryExample = new CmsCategoryExample();
+        cmsCategoryExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId())
+                .andAliasEqualTo(alias);
+        CmsCategory category = cmsCategoryService.selectFirstByExample(cmsCategoryExample);
+        model.addAttribute("category", category);
+        // 该类目文章列表
+        int rows = 10;
+        List<CmsArticle> articles = cmsArticleService.selectCmsArticlesByCategoryId(category.getCategoryId(), (page - 1) * rows, rows);
+        model.addAttribute("articles", articles);
+        // 文章总数
+        long total = cmsArticleService.countByCategoryId(category.getCategoryId());
+        // 分页
+        Paginator paginator = new Paginator(total, page, rows, request);
+        model.addAttribute("paginator", paginator);
+        return thymeleaf("/qa/category/index");
+    }
+
+    @RequestMapping(value = "/tag/{alias}", method = RequestMethod.GET)
+    public String tag(@PathVariable("alias") String alias,
+                      @RequestParam(required = false, defaultValue = "1", value = "page") int page,
+                      HttpServletRequest request,
+                      Model model) {
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 当前标签
+        CmsTagExample cmsTagExample = new CmsTagExample();
+        cmsTagExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId())
+                .andAliasEqualTo(alias);
+        CmsTag tag = cmsTagService.selectFirstByExample(cmsTagExample);
+        model.addAttribute("tag", tag);
+        // 该标签文章列表
+        int rows = 10;
+        List<CmsArticle> articles = cmsArticleService.selectCmsArticlesByTagId(tag.getTagId(), (page - 1) * rows, rows);
+        model.addAttribute("articles", articles);
+        // 文章总数
+        long total = cmsArticleService.countByTagId(tag.getTagId());
+        // 分页
+        Paginator paginator = new Paginator(total, page, rows, request);
+        model.addAttribute("paginator", paginator);
+        return thymeleaf("/qa/tag/index");
+    }
+
+    @RequestMapping(value = "/question/{articleId}", method = RequestMethod.GET)
+    public String question(@PathVariable("articleId") int articleId, Model model) {
+        CmsArticle article = cmsArticleService.selectByPrimaryKey(articleId);
+        model.addAttribute("article", article);
+        // 系统id
+        CmsSystemExample cmsSystemExample = new CmsSystemExample();
+        cmsSystemExample.createCriteria()
+                .andCodeEqualTo(CODE);
+        CmsSystem system = cmsSystemService.selectFirstByExample(cmsSystemExample);
+        model.addAttribute("system", system);
+        // 评论列表
+        CmsCommentExample cmsCommentExample = new CmsCommentExample();
+        cmsCommentExample.createCriteria()
+                .andSystemIdEqualTo(system.getSystemId())
+                .andArticleIdEqualTo(articleId)
+                .andStatusEqualTo((byte) 1);
+        cmsCommentExample.setOrderByClause("ctime desc");
+        List<CmsComment> comments = cmsCommentService.selectByExampleWithBLOBs(cmsCommentExample);
+        model.addAttribute("comments", comments);
+        return thymeleaf("/qa/question/index");
+    }
+
 }

+ 0 - 73
zheng-cms/zheng-cms-web/src/main/java/com/zheng/cms/web/controller/TagController.java

@@ -1,73 +0,0 @@
-package com.zheng.cms.web.controller;
-
-import com.zheng.cms.dao.model.*;
-import com.zheng.cms.rpc.api.CmsArticleService;
-import com.zheng.cms.rpc.api.CmsCategoryService;
-import com.zheng.cms.rpc.api.CmsTagService;
-import com.zheng.cms.rpc.api.CmsTopicService;
-import com.zheng.common.base.BaseController;
-import com.zheng.common.util.Paginator;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.List;
-
-/**
- * 标签控制器
- * Created by shuzheng on 2017/3/26.
- */
-@Controller
-@RequestMapping(value = "/tag")
-public class TagController extends BaseController {
-
-	private static Logger _log = LoggerFactory.getLogger(TagController.class);
-
-	@Autowired
-	private CmsTagService cmsTagService;
-
-	@Autowired
-	private CmsArticleService cmsArticleService;
-
-	@RequestMapping(value = "/{alias}", method = RequestMethod.GET)
-	public String index(@PathVariable("alias") String alias,
-						@RequestParam(required = false, defaultValue = "1", value = "page") int page,
-						@RequestParam(required = false, defaultValue = "orders", value = "sort") String sort,
-						@RequestParam(required = false, defaultValue = "desc", value = "order") String order,
-						HttpServletRequest request,
-						Model model) {
-		// 当前标签
-		CmsTagExample cmsTagExample = new CmsTagExample();
-		cmsTagExample.createCriteria()
-				.andAliasEqualTo(alias);
-		CmsTag tag = cmsTagService.selectFirstByExample(cmsTagExample);
-		model.addAttribute("tag", tag);
-		// 该标签文章列表
-		int rows = 10;
-		CmsArticleExample cmsArticleExample = new CmsArticleExample();
-		cmsArticleExample.createCriteria()
-				.andStatusEqualTo((byte) 1);
-		cmsArticleExample.setOffset((page - 1) * rows);
-		cmsArticleExample.setLimit(rows);
-		if (!StringUtils.isBlank(sort) && !StringUtils.isBlank(order)) {
-			cmsArticleExample.setOrderByClause(sort + " " + order);
-		}
-		List<CmsArticle> articles = cmsArticleService.selectByExample(cmsArticleExample);
-		model.addAttribute("articles", articles);
-		// 文章总数
-		long total = cmsArticleService.countByExample(cmsArticleExample);
-		// 分页
-		Paginator paginator = new Paginator(total, page, rows, request);
-		model.addAttribute("paginator", paginator);
-		return thymeleaf("/tag/index");
-	}
-
-}

+ 109 - 0
zheng-ui/zheng-cms-web/blog/category/index.html

@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
+<head>
+    <meta charset="utf-8"/>
+    <title th:text="${category.name} + ' - ZhengCms'">类目 - ZhengCms</title>
+    <meta name="keywords" content=""/>
+    <meta name="description" content=""/>
+    <meta name="renderer" content="webkit"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="shortcut icon" href="../../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
+    <link rel="stylesheet" href="../../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
+    <!--[if lt IE 9]>
+    <script src="../../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
+    <script src="../../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
+    <![endif]-->
+    <script type="text/javascript">
+        if (/msie [6|7|8]/i.test(navigator.userAgent)) {};
+    </script>
+    <link rel="stylesheet" href="../../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
+</head>
+<body>
+<!-- .navbar -->
+<nav class="navbar navbar-inverse navbar-fixed-top"><!--navbar-inverse-->
+    <div class="container">
+        <!-- navbar-header -->
+        <div class="navbar-header">
+            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-menu">
+                <span class="sr-only">切换菜单</span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </button>
+            <a class="navbar-brand" href="../../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
+            <p class="navbar-text hidden-sm">最简约的内容管理系统</p>
+        </div>
+        <!-- /.navbar-header -->
+        <!-- navbar-collapse -->
+        <div class="collapse navbar-collapse" id="nav-menu">
+            <ul class="nav navbar-nav">
+                <li th:each="menu : ${menus}" th:if="${menu.pid} == null"><a th:href="@{${menu.url}}" th:target="${menu.target}" th:text="${menu.name}">菜单</a></li>
+            </ul>
+            <ul class="nav navbar-right navbar-nav">
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-search"></span></a>
+                    <ul class="dropdown-menu">
+                        <form id="search-form" class="form-inline">
+                            <div class="input-group">
+                                <input id="keywords" type="text" name="keywords" class="form-control" placeholder="搜索"/>
+                                <div class="input-group-btn">
+                                    <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
+                                </div>
+                            </div>
+                        </form>
+                    </ul>
+                </li>
+                <li><a href="login.html">登录</a></li>
+                <li><a href="reg.html">注册</a></li>
+                <li id="messages" class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-bell"></span>
+                        <span class="badge bg-important">5</span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/letter.html"><span class="glyphicon glyphicon-envelope"></span> 我的私信(<span class="msg-txt">1</span>)</a></li>
+                        <li><a href="home/message.html"><span class="glyphicon glyphicon-volume-up"></span> 系统消息(<span class="msg-txt">4</span>)</a></li>
+                    </ul>
+                </li>
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-user"></span>
+                        <span class="caret"></span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/index.html"><span class="glyphicon glyphicon-home"></span> 个人博客</a></li>
+                        <li><a href="home/question.html"><span class="glyphicon glyphicon-question-sign"></span> 我的提问</a></li>
+                        <li><a href="home/answer.html"><span class="glyphicon glyphicon-ok-sign"></span> 我的回答</a></li>
+                        <li><a href="home/collection.html"><span class="glyphicon glyphicon-star"></span> 我的收藏</a></li>
+                        <li class="divider"></li>
+                        <li><a href="setting/info.html"><span class="glyphicon glyphicon-cog"></span> 修改资料</a></li>
+                        <li><a href="setting/password.html"><span class="glyphicon glyphicon-lock"></span> 密码安全</a></li>
+                        <li><a href="logout.html"><span class="glyphicon glyphicon-log-out"></span> 安全退出</a></li>
+                    </ul>
+                </li>
+            </ul>
+        </div>
+        <!-- /.navbar-collapse -->
+    </div>
+</nav>
+<!-- /.navbar -->
+<!-- .container -->
+<div class="container" style="padding-bottom:80px;">
+    <dl>
+        <dt><span th:text="${category.name}">类目</span>博文列表</dt>
+        <dd th:each="article : ${articles}"><a href="../blog/details/index.html" th:href="@{'/blog/details/' + ${article.articleId}}" th:text="${article.title}">博文标题</a></dd>
+    </dl>
+    <div th:utext="${paginator.html}"></div>
+</div>
+<!-- /.container -->
+<!-- footer -->
+<footer class="container-fuild text-center" style="position:fixed;bottom:0;width:100%;background:#eee;padding:20px 0;">
+    Copyright &copy; 2017 ZhangShuzheng All Rights Reserved
+</footer>
+<!-- /footer -->
+<script src="../../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
+<script src="../../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
+<script src="../../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
+</body>
+</html>

+ 9 - 9
zheng-ui/zheng-cms-web/article/index.html → zheng-ui/zheng-cms-web/blog/details/index.html

@@ -8,16 +8,16 @@
     <meta name="renderer" content="webkit"/>
     <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
     <meta name="viewport" content="width=device-width, initial-scale=1"/>
-    <link rel="shortcut icon" href="../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
-    <link rel="stylesheet" href="../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
+    <link rel="shortcut icon" href="../../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
+    <link rel="stylesheet" href="../../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
     <!--[if lt IE 9]>
-    <script src="../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
-    <script src="../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
+    <script src="../../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
+    <script src="../../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
     <![endif]-->
     <script type="text/javascript">
         if (/msie [6|7|8]/i.test(navigator.userAgent)) {};
     </script>
-    <link rel="stylesheet" href="../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
+    <link rel="stylesheet" href="../../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
 </head>
 <body>
 <!-- .navbar -->
@@ -31,7 +31,7 @@
                 <span class="icon-bar"></span>
                 <span class="icon-bar"></span>
             </button>
-            <a class="navbar-brand" href="../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
+            <a class="navbar-brand" href="../../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
             <p class="navbar-text hidden-sm">最简约的内容管理系统</p>
         </div>
         <!-- /.navbar-header -->
@@ -107,9 +107,9 @@
     Copyright &copy; 2017 ZhangShuzheng All Rights Reserved
 </footer>
 <!-- /footer -->
-<script src="../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
-<script src="../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
-<script src="../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
+<script src="../../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
+<script src="../../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
+<script src="../../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
 <script>
 $('#submit').click(function () {
     $.post($('#commentForm').attr('action'), $('#commentForm').serialize(), function (json) {

+ 14 - 2
zheng-ui/zheng-cms-web/blog/index.html

@@ -2,7 +2,7 @@
 <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
 <head>
     <meta charset="utf-8"/>
-    <title>博客首页 - ZhengCms</title>
+    <title>资讯首页 - ZhengCms</title>
     <meta name="keywords" content=""/>
     <meta name="description" content=""/>
     <meta name="renderer" content="webkit"/>
@@ -90,7 +90,19 @@
 <!-- /.navbar -->
 <!-- .container -->
 <div class="container" style="padding-bottom:80px;">
-    博客首页
+    <dl>
+        <dt>博客类目</dt>
+        <dd th:each="category : ${categories}"><a href="category/index.html" th:href="@{'/blog/category/' + ${category.alias}}" th:text="${category.name}">类目</a></dd>
+    </dl>
+    <dl>
+        <dt>博客标签</dt>
+        <dd th:each="tag : ${tags}"><a href="tag/index.html" th:href="@{'/blog/tag/' + ${tag.alias}}" th:text="${tag.name}">标签</a></dd>
+    </dl>
+    <dl>
+        <dt>博客博文列表</dt>
+        <dd th:each="article : ${articles}"><a href="details/index.html" th:href="@{'/blog/details/' + ${article.articleId}}" th:text="${article.title}">博文标题</a></dd>
+    </dl>
+    <div th:utext="${paginator.html}"></div>
 </div>
 <!-- /.container -->
 <!-- footer -->

+ 109 - 0
zheng-ui/zheng-cms-web/blog/tag/index.html

@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
+<head>
+    <meta charset="utf-8"/>
+    <title th:text="${tag.name} + ' - ZhengCms'">标签 - ZhengCms</title>
+    <meta name="keywords" content=""/>
+    <meta name="description" content=""/>
+    <meta name="renderer" content="webkit"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="shortcut icon" href="../../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
+    <link rel="stylesheet" href="../../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
+    <!--[if lt IE 9]>
+    <script src="../../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
+    <script src="../../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
+    <![endif]-->
+    <script type="text/javascript">
+        if (/msie [6|7|8]/i.test(navigator.userAgent)) {};
+    </script>
+    <link rel="stylesheet" href="../../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
+</head>
+<body>
+<!-- .navbar -->
+<nav class="navbar navbar-inverse navbar-fixed-top"><!--navbar-inverse-->
+    <div class="container">
+        <!-- navbar-header -->
+        <div class="navbar-header">
+            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-menu">
+                <span class="sr-only">切换菜单</span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </button>
+            <a class="navbar-brand" href="../../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
+            <p class="navbar-text hidden-sm">最简约的内容管理系统</p>
+        </div>
+        <!-- /.navbar-header -->
+        <!-- navbar-collapse -->
+        <div class="collapse navbar-collapse" id="nav-menu">
+            <ul class="nav navbar-nav">
+                <li th:each="menu : ${menus}" th:if="${menu.pid} == null"><a th:href="@{${menu.url}}" th:target="${menu.target}" th:text="${menu.name}">菜单</a></li>
+            </ul>
+            <ul class="nav navbar-right navbar-nav">
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-search"></span></a>
+                    <ul class="dropdown-menu">
+                        <form id="search-form" class="form-inline">
+                            <div class="input-group">
+                                <input id="keywords" type="text" name="keywords" class="form-control" placeholder="搜索"/>
+                                <div class="input-group-btn">
+                                    <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
+                                </div>
+                            </div>
+                        </form>
+                    </ul>
+                </li>
+                <li><a href="login.html">登录</a></li>
+                <li><a href="reg.html">注册</a></li>
+                <li id="messages" class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-bell"></span>
+                        <span class="badge bg-important">5</span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/letter.html"><span class="glyphicon glyphicon-envelope"></span> 我的私信(<span class="msg-txt">1</span>)</a></li>
+                        <li><a href="home/message.html"><span class="glyphicon glyphicon-volume-up"></span> 系统消息(<span class="msg-txt">4</span>)</a></li>
+                    </ul>
+                </li>
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-user"></span>
+                        <span class="caret"></span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/index.html"><span class="glyphicon glyphicon-home"></span> 个人博客</a></li>
+                        <li><a href="home/question.html"><span class="glyphicon glyphicon-question-sign"></span> 我的提问</a></li>
+                        <li><a href="home/answer.html"><span class="glyphicon glyphicon-ok-sign"></span> 我的回答</a></li>
+                        <li><a href="home/collection.html"><span class="glyphicon glyphicon-star"></span> 我的收藏</a></li>
+                        <li class="divider"></li>
+                        <li><a href="setting/info.html"><span class="glyphicon glyphicon-cog"></span> 修改资料</a></li>
+                        <li><a href="setting/password.html"><span class="glyphicon glyphicon-lock"></span> 密码安全</a></li>
+                        <li><a href="logout.html"><span class="glyphicon glyphicon-log-out"></span> 安全退出</a></li>
+                    </ul>
+                </li>
+            </ul>
+        </div>
+        <!-- /.navbar-collapse -->
+    </div>
+</nav>
+<!-- /.navbar -->
+<!-- .container -->
+<div class="container" style="padding-bottom:80px;">
+    <dl>
+        <dt><span th:text="${tag.name}">标签</span>博文列表</dt>
+        <dd th:each="article : ${articles}"><a href="../blog/details/index.html" th:href="@{'/blog/details/' + ${article.articleId}}" th:text="${article.title}">博文标题</a></dd>
+    </dl>
+    <div th:utext="${paginator.html}"></div>
+</div>
+<!-- /.container -->
+<!-- footer -->
+<footer class="container-fuild text-center" style="position:fixed;bottom:0;width:100%;background:#eee;padding:20px 0;">
+    Copyright &copy; 2017 ZhangShuzheng All Rights Reserved
+</footer>
+<!-- /footer -->
+<script src="../../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
+<script src="../../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
+<script src="../../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
+</body>
+</html>

+ 6 - 14
zheng-ui/zheng-cms-web/index.html

@@ -91,24 +91,16 @@
 <!-- .container -->
 <div class="container" style="padding-bottom:80px;">
     <dl>
-        <dt>所有类目</dt>
-        <dd th:each="category : ${categories}"><a href="category/index.html" th:href="@{'/category/' + ${category.alias}}" th:text="${category.name}">类目</a></dd>
-    </dl>
-    <dl>
-        <dt>所有标签</dt>
-        <dd th:each="tag : ${tags}"><a href="tag/index.html" th:href="@{'/tag/' + ${tag.alias}}" th:text="${tag.name}">标签</a></dd>
+        <dt>所有系统</dt>
+        <dd th:each="system : ${systems}" th:text="${system.name}">系统名称</dd>
     </dl>
     <dl>
-        <dt>最新5个专题</dt>
-        <dd th:each="topic : ${topics}"><a href="topic/index.html" th:href="@{${topic.url}}" th:text="${topic.title}">专题</a></dd>
-    </dl>
-    <dl>
-        <dt>最新5条文章</dt>
-        <dd th:each="newArticle : ${newArticles}"><a href="article/index.html" th:href="@{'/article/' + ${newArticle.articleId}}" th:text="${newArticle.title}">文章标题</a></dd>
+        <dt>所有类目</dt>
+        <dd th:each="category : ${categories}"><a href="news/category/index.html" th:href="@{'/category/' + ${category.alias}}" th:text="${category.name}">类目</a></dd>
     </dl>
     <dl>
-        <dt>最热5个文章</dt>
-        <dd th:each="hotArticle : ${hotArticles}"><a href="article/index.html" th:href="@{'/article/' + ${hotArticle.articleId}}" th:text="${hotArticle.title}">文章标题</a></dd>
+        <dt>所有标签</dt>
+        <dd th:each="tag : ${tags}"><a href="news/tag/index.html" th:href="@{'/tag/' + ${tag.alias}}" th:text="${tag.name}">标签</a></dd>
     </dl>
 </div>
 <!-- /.container -->

+ 125 - 0
zheng-ui/zheng-cms-web/news/article/index.html

@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
+<head>
+    <meta charset="utf-8"/>
+    <title th:text="${article.title} + ' - ZhengCms'">标题 - ZhengCms</title>
+    <meta name="keywords" content=""/>
+    <meta name="description" content=""/>
+    <meta name="renderer" content="webkit"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="shortcut icon" href="../../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
+    <link rel="stylesheet" href="../../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
+    <!--[if lt IE 9]>
+    <script src="../../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
+    <script src="../../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
+    <![endif]-->
+    <script type="text/javascript">
+        if (/msie [6|7|8]/i.test(navigator.userAgent)) {};
+    </script>
+    <link rel="stylesheet" href="../../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
+</head>
+<body>
+<!-- .navbar -->
+<nav class="navbar navbar-inverse navbar-fixed-top"><!--navbar-inverse-->
+    <div class="container">
+        <!-- navbar-header -->
+        <div class="navbar-header">
+            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-menu">
+                <span class="sr-only">切换菜单</span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </button>
+            <a class="navbar-brand" href="../../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
+            <p class="navbar-text hidden-sm">最简约的内容管理系统</p>
+        </div>
+        <!-- /.navbar-header -->
+        <!-- navbar-collapse -->
+        <div class="collapse navbar-collapse" id="nav-menu">
+            <ul class="nav navbar-nav">
+                <li th:each="menu : ${menus}" th:if="${menu.pid} == null"><a th:href="@{${menu.url}}" th:target="${menu.target}" th:text="${menu.name}">菜单</a></li>
+            </ul>
+            <ul class="nav navbar-right navbar-nav">
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-search"></span></a>
+                    <ul class="dropdown-menu">
+                        <form id="search-form" class="form-inline">
+                            <div class="input-group">
+                                <input id="keywords" type="text" name="keywords" class="form-control" placeholder="搜索"/>
+                                <div class="input-group-btn">
+                                    <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
+                                </div>
+                            </div>
+                        </form>
+                    </ul>
+                </li>
+                <li><a href="login.html">登录</a></li>
+                <li><a href="reg.html">注册</a></li>
+                <li id="messages" class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-bell"></span>
+                        <span class="badge bg-important">5</span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/letter.html"><span class="glyphicon glyphicon-envelope"></span> 我的私信(<span class="msg-txt">1</span>)</a></li>
+                        <li><a href="home/message.html"><span class="glyphicon glyphicon-volume-up"></span> 系统消息(<span class="msg-txt">4</span>)</a></li>
+                    </ul>
+                </li>
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-user"></span>
+                        <span class="caret"></span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/index.html"><span class="glyphicon glyphicon-home"></span> 个人博客</a></li>
+                        <li><a href="home/question.html"><span class="glyphicon glyphicon-question-sign"></span> 我的提问</a></li>
+                        <li><a href="home/answer.html"><span class="glyphicon glyphicon-ok-sign"></span> 我的回答</a></li>
+                        <li><a href="home/collection.html"><span class="glyphicon glyphicon-star"></span> 我的收藏</a></li>
+                        <li class="divider"></li>
+                        <li><a href="setting/info.html"><span class="glyphicon glyphicon-cog"></span> 修改资料</a></li>
+                        <li><a href="setting/password.html"><span class="glyphicon glyphicon-lock"></span> 密码安全</a></li>
+                        <li><a href="logout.html"><span class="glyphicon glyphicon-log-out"></span> 安全退出</a></li>
+                    </ul>
+                </li>
+            </ul>
+        </div>
+        <!-- /.navbar-collapse -->
+    </div>
+</nav>
+<!-- /.navbar -->
+<!-- .container -->
+<div class="container" style="padding-bottom:80px;">
+    <h3 th:text="${article.title}">标题</h3>
+    <div th:utext="${article.content}">内容</div>
+    <form id="commentForm" th:action="@{'/comment/create/' + ${article.articleId}}" method="post">
+        <textarea id="" name="content" style="width:100%;height:50px;"></textarea>
+        <input id="submit" type="button" value="评论"/><!--{"code":1,"message":"success","data":1}-->
+    </form>
+    <dl>
+        <dt>评论列表</dt>
+        <dd th:each="comment : ${comments}" th:utext="${comment.content}">评论内容</dd>
+    </dl>
+</div>
+<!-- /.container -->
+<!-- footer -->
+<footer class="container-fuild text-center" style="position:fixed;bottom:0;width:100%;background:#eee;padding:20px 0;">
+    Copyright &copy; 2017 ZhangShuzheng All Rights Reserved
+</footer>
+<!-- /footer -->
+<script src="../../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
+<script src="../../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
+<script src="../../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
+<script>
+$('#submit').click(function () {
+    $.post($('#commentForm').attr('action'), $('#commentForm').serialize(), function (json) {
+        if (json.code == 1) {
+            location.reload();
+        } else {
+            alert(json.data);
+        }
+    })
+});
+</script>
+</body>
+</html>

+ 10 - 10
zheng-ui/zheng-cms-web/category/index.html → zheng-ui/zheng-cms-web/news/category/index.html

@@ -8,16 +8,16 @@
     <meta name="renderer" content="webkit"/>
     <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
     <meta name="viewport" content="width=device-width, initial-scale=1"/>
-    <link rel="shortcut icon" href="../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
-    <link rel="stylesheet" href="../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
+    <link rel="shortcut icon" href="../../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
+    <link rel="stylesheet" href="../../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
     <!--[if lt IE 9]>
-    <script src="../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
-    <script src="../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
+    <script src="../../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
+    <script src="../../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
     <![endif]-->
     <script type="text/javascript">
         if (/msie [6|7|8]/i.test(navigator.userAgent)) {};
     </script>
-    <link rel="stylesheet" href="../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
+    <link rel="stylesheet" href="../../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
 </head>
 <body>
 <!-- .navbar -->
@@ -31,7 +31,7 @@
                 <span class="icon-bar"></span>
                 <span class="icon-bar"></span>
             </button>
-            <a class="navbar-brand" href="../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
+            <a class="navbar-brand" href="../../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
             <p class="navbar-text hidden-sm">最简约的内容管理系统</p>
         </div>
         <!-- /.navbar-header -->
@@ -92,7 +92,7 @@
 <div class="container" style="padding-bottom:80px;">
     <dl>
         <dt><span th:text="${category.name}">类目</span>文章列表</dt>
-        <dd th:each="article : ${articles}"><a href="../article/index.html" th:href="@{'/article/' + ${article.articleId}}" th:text="${article.title}">文章标题</a></dd>
+        <dd th:each="article : ${articles}"><a href="../news/article/index.html" th:href="@{'/news/article/' + ${article.articleId}}" th:text="${article.title}">文章标题</a></dd>
     </dl>
     <div th:utext="${paginator.html}"></div>
 </div>
@@ -102,8 +102,8 @@
     Copyright &copy; 2017 ZhangShuzheng All Rights Reserved
 </footer>
 <!-- /footer -->
-<script src="../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
-<script src="../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
-<script src="../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
+<script src="../../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
+<script src="../../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
+<script src="../../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
 </body>
 </html>

+ 13 - 1
zheng-ui/zheng-cms-web/news/index.html

@@ -90,7 +90,19 @@
 <!-- /.navbar -->
 <!-- .container -->
 <div class="container" style="padding-bottom:80px;">
-    资讯首页
+    <dl>
+        <dt>资讯类目</dt>
+        <dd th:each="category : ${categories}"><a href="category/index.html" th:href="@{'/news/category/' + ${category.alias}}" th:text="${category.name}">类目</a></dd>
+    </dl>
+    <dl>
+        <dt>资讯标签</dt>
+        <dd th:each="tag : ${tags}"><a href="tag/index.html" th:href="@{'/news/tag/' + ${tag.alias}}" th:text="${tag.name}">标签</a></dd>
+    </dl>
+    <dl>
+        <dt>资讯文章列表</dt>
+        <dd th:each="article : ${articles}"><a href="article/index.html" th:href="@{'/news/article/' + ${article.articleId}}" th:text="${article.title}">文章标题</a></dd>
+    </dl>
+    <div th:utext="${paginator.html}"></div>
 </div>
 <!-- /.container -->
 <!-- footer -->

+ 10 - 10
zheng-ui/zheng-cms-web/tag/index.html → zheng-ui/zheng-cms-web/news/tag/index.html

@@ -8,16 +8,16 @@
     <meta name="renderer" content="webkit"/>
     <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
     <meta name="viewport" content="width=device-width, initial-scale=1"/>
-    <link rel="shortcut icon" href="../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
-    <link rel="stylesheet" href="../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
+    <link rel="shortcut icon" href="../../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
+    <link rel="stylesheet" href="../../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
     <!--[if lt IE 9]>
-    <script src="../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
-    <script src="../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
+    <script src="../../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
+    <script src="../../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
     <![endif]-->
     <script type="text/javascript">
         if (/msie [6|7|8]/i.test(navigator.userAgent)) {};
     </script>
-    <link rel="stylesheet" href="../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
+    <link rel="stylesheet" href="../../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
 </head>
 <body>
 <!-- .navbar -->
@@ -31,7 +31,7 @@
                 <span class="icon-bar"></span>
                 <span class="icon-bar"></span>
             </button>
-            <a class="navbar-brand" href="../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
+            <a class="navbar-brand" href="../../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
             <p class="navbar-text hidden-sm">最简约的内容管理系统</p>
         </div>
         <!-- /.navbar-header -->
@@ -92,7 +92,7 @@
 <div class="container" style="padding-bottom:80px;">
     <dl>
         <dt><span th:text="${tag.name}">标签</span>文章列表</dt>
-        <dd th:each="article : ${articles}"><a href="../article/index.html" th:href="@{'/article/' + ${article.articleId}}" th:text="${article.title}">文章标题</a></dd>
+        <dd th:each="article : ${articles}"><a href="../news/article/index.html" th:href="@{'/news/article/' + ${article.articleId}}" th:text="${article.title}">文章标题</a></dd>
     </dl>
     <div th:utext="${paginator.html}"></div>
 </div>
@@ -102,8 +102,8 @@
     Copyright &copy; 2017 ZhangShuzheng All Rights Reserved
 </footer>
 <!-- /footer -->
-<script src="../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
-<script src="../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
-<script src="../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
+<script src="../../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
+<script src="../../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
+<script src="../../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
 </body>
 </html>

+ 109 - 0
zheng-ui/zheng-cms-web/qa/category/index.html

@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
+<head>
+    <meta charset="utf-8"/>
+    <title th:text="${category.name} + ' - ZhengCms'">类目 - ZhengCms</title>
+    <meta name="keywords" content=""/>
+    <meta name="description" content=""/>
+    <meta name="renderer" content="webkit"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="shortcut icon" href="../../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
+    <link rel="stylesheet" href="../../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
+    <!--[if lt IE 9]>
+    <script src="../../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
+    <script src="../../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
+    <![endif]-->
+    <script type="text/javascript">
+        if (/msie [6|7|8]/i.test(navigator.userAgent)) {};
+    </script>
+    <link rel="stylesheet" href="../../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
+</head>
+<body>
+<!-- .navbar -->
+<nav class="navbar navbar-inverse navbar-fixed-top"><!--navbar-inverse-->
+    <div class="container">
+        <!-- navbar-header -->
+        <div class="navbar-header">
+            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-menu">
+                <span class="sr-only">切换菜单</span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </button>
+            <a class="navbar-brand" href="../../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
+            <p class="navbar-text hidden-sm">最简约的内容管理系统</p>
+        </div>
+        <!-- /.navbar-header -->
+        <!-- navbar-collapse -->
+        <div class="collapse navbar-collapse" id="nav-menu">
+            <ul class="nav navbar-nav">
+                <li th:each="menu : ${menus}" th:if="${menu.pid} == null"><a th:href="@{${menu.url}}" th:target="${menu.target}" th:text="${menu.name}">菜单</a></li>
+            </ul>
+            <ul class="nav navbar-right navbar-nav">
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-search"></span></a>
+                    <ul class="dropdown-menu">
+                        <form id="search-form" class="form-inline">
+                            <div class="input-group">
+                                <input id="keywords" type="text" name="keywords" class="form-control" placeholder="搜索"/>
+                                <div class="input-group-btn">
+                                    <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
+                                </div>
+                            </div>
+                        </form>
+                    </ul>
+                </li>
+                <li><a href="login.html">登录</a></li>
+                <li><a href="reg.html">注册</a></li>
+                <li id="messages" class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-bell"></span>
+                        <span class="badge bg-important">5</span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/letter.html"><span class="glyphicon glyphicon-envelope"></span> 我的私信(<span class="msg-txt">1</span>)</a></li>
+                        <li><a href="home/message.html"><span class="glyphicon glyphicon-volume-up"></span> 系统消息(<span class="msg-txt">4</span>)</a></li>
+                    </ul>
+                </li>
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-user"></span>
+                        <span class="caret"></span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/index.html"><span class="glyphicon glyphicon-home"></span> 个人博客</a></li>
+                        <li><a href="home/question.html"><span class="glyphicon glyphicon-question-sign"></span> 我的提问</a></li>
+                        <li><a href="home/answer.html"><span class="glyphicon glyphicon-ok-sign"></span> 我的回答</a></li>
+                        <li><a href="home/collection.html"><span class="glyphicon glyphicon-star"></span> 我的收藏</a></li>
+                        <li class="divider"></li>
+                        <li><a href="setting/info.html"><span class="glyphicon glyphicon-cog"></span> 修改资料</a></li>
+                        <li><a href="setting/password.html"><span class="glyphicon glyphicon-lock"></span> 密码安全</a></li>
+                        <li><a href="logout.html"><span class="glyphicon glyphicon-log-out"></span> 安全退出</a></li>
+                    </ul>
+                </li>
+            </ul>
+        </div>
+        <!-- /.navbar-collapse -->
+    </div>
+</nav>
+<!-- /.navbar -->
+<!-- .container -->
+<div class="container" style="padding-bottom:80px;">
+    <dl>
+        <dt><span th:text="${category.name}">类目</span>问题列表</dt>
+        <dd th:each="article : ${articles}"><a href="../qa/question/index.html" th:href="@{'/qa/question/' + ${article.articleId}}" th:text="${article.title}">问题标题</a></dd>
+    </dl>
+    <div th:utext="${paginator.html}"></div>
+</div>
+<!-- /.container -->
+<!-- footer -->
+<footer class="container-fuild text-center" style="position:fixed;bottom:0;width:100%;background:#eee;padding:20px 0;">
+    Copyright &copy; 2017 ZhangShuzheng All Rights Reserved
+</footer>
+<!-- /footer -->
+<script src="../../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
+<script src="../../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
+<script src="../../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
+</body>
+</html>

+ 13 - 1
zheng-ui/zheng-cms-web/qa/index.html

@@ -90,7 +90,19 @@
 <!-- /.navbar -->
 <!-- .container -->
 <div class="container" style="padding-bottom:80px;">
-    问答首页
+    <dl>
+        <dt>问答类目</dt>
+        <dd th:each="category : ${categories}"><a href="category/index.html" th:href="@{'/qa/category/' + ${category.alias}}" th:text="${category.name}">类目</a></dd>
+    </dl>
+    <dl>
+        <dt>问答标签</dt>
+        <dd th:each="tag : ${tags}"><a href="tag/index.html" th:href="@{'/qa/tag/' + ${tag.alias}}" th:text="${tag.name}">标签</a></dd>
+    </dl>
+    <dl>
+        <dt>问答问题列表</dt>
+        <dd th:each="article : ${articles}"><a href="article/index.html" th:href="@{'/qa/question/' + ${article.articleId}}" th:text="${article.title}">问题标题</a></dd>
+    </dl>
+    <div th:utext="${paginator.html}"></div>
 </div>
 <!-- /.container -->
 <!-- footer -->

+ 125 - 0
zheng-ui/zheng-cms-web/qa/question/index.html

@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
+<head>
+    <meta charset="utf-8"/>
+    <title th:text="${article.title} + ' - ZhengCms'">标题 - ZhengCms</title>
+    <meta name="keywords" content=""/>
+    <meta name="description" content=""/>
+    <meta name="renderer" content="webkit"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="shortcut icon" href="../../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
+    <link rel="stylesheet" href="../../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
+    <!--[if lt IE 9]>
+    <script src="../../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
+    <script src="../../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
+    <![endif]-->
+    <script type="text/javascript">
+        if (/msie [6|7|8]/i.test(navigator.userAgent)) {};
+    </script>
+    <link rel="stylesheet" href="../../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
+</head>
+<body>
+<!-- .navbar -->
+<nav class="navbar navbar-inverse navbar-fixed-top"><!--navbar-inverse-->
+    <div class="container">
+        <!-- navbar-header -->
+        <div class="navbar-header">
+            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-menu">
+                <span class="sr-only">切换菜单</span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </button>
+            <a class="navbar-brand" href="../../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
+            <p class="navbar-text hidden-sm">最简约的内容管理系统</p>
+        </div>
+        <!-- /.navbar-header -->
+        <!-- navbar-collapse -->
+        <div class="collapse navbar-collapse" id="nav-menu">
+            <ul class="nav navbar-nav">
+                <li th:each="menu : ${menus}" th:if="${menu.pid} == null"><a th:href="@{${menu.url}}" th:target="${menu.target}" th:text="${menu.name}">菜单</a></li>
+            </ul>
+            <ul class="nav navbar-right navbar-nav">
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-search"></span></a>
+                    <ul class="dropdown-menu">
+                        <form id="search-form" class="form-inline">
+                            <div class="input-group">
+                                <input id="keywords" type="text" name="keywords" class="form-control" placeholder="搜索"/>
+                                <div class="input-group-btn">
+                                    <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
+                                </div>
+                            </div>
+                        </form>
+                    </ul>
+                </li>
+                <li><a href="login.html">登录</a></li>
+                <li><a href="reg.html">注册</a></li>
+                <li id="messages" class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-bell"></span>
+                        <span class="badge bg-important">5</span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/letter.html"><span class="glyphicon glyphicon-envelope"></span> 我的私信(<span class="msg-txt">1</span>)</a></li>
+                        <li><a href="home/message.html"><span class="glyphicon glyphicon-volume-up"></span> 系统消息(<span class="msg-txt">4</span>)</a></li>
+                    </ul>
+                </li>
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-user"></span>
+                        <span class="caret"></span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/index.html"><span class="glyphicon glyphicon-home"></span> 个人博客</a></li>
+                        <li><a href="home/question.html"><span class="glyphicon glyphicon-question-sign"></span> 我的提问</a></li>
+                        <li><a href="home/answer.html"><span class="glyphicon glyphicon-ok-sign"></span> 我的回答</a></li>
+                        <li><a href="home/collection.html"><span class="glyphicon glyphicon-star"></span> 我的收藏</a></li>
+                        <li class="divider"></li>
+                        <li><a href="setting/info.html"><span class="glyphicon glyphicon-cog"></span> 修改资料</a></li>
+                        <li><a href="setting/password.html"><span class="glyphicon glyphicon-lock"></span> 密码安全</a></li>
+                        <li><a href="logout.html"><span class="glyphicon glyphicon-log-out"></span> 安全退出</a></li>
+                    </ul>
+                </li>
+            </ul>
+        </div>
+        <!-- /.navbar-collapse -->
+    </div>
+</nav>
+<!-- /.navbar -->
+<!-- .container -->
+<div class="container" style="padding-bottom:80px;">
+    <h3 th:text="${article.title}">标题</h3>
+    <div th:utext="${article.content}">内容</div>
+    <form id="commentForm" th:action="@{'/comment/create/' + ${article.articleId}}" method="post">
+        <textarea id="" name="content" style="width:100%;height:50px;"></textarea>
+        <input id="submit" type="button" value="回答"/><!--{"code":1,"message":"success","data":1}-->
+    </form>
+    <dl>
+        <dt>回答列表</dt>
+        <dd th:each="comment : ${comments}" th:utext="${comment.content}">回答内容</dd>
+    </dl>
+</div>
+<!-- /.container -->
+<!-- footer -->
+<footer class="container-fuild text-center" style="position:fixed;bottom:0;width:100%;background:#eee;padding:20px 0;">
+    Copyright &copy; 2017 ZhangShuzheng All Rights Reserved
+</footer>
+<!-- /footer -->
+<script src="../../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
+<script src="../../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
+<script src="../../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
+<script>
+$('#submit').click(function () {
+    $.post($('#commentForm').attr('action'), $('#commentForm').serialize(), function (json) {
+        if (json.code == 1) {
+            location.reload();
+        } else {
+            alert(json.data);
+        }
+    })
+});
+</script>
+</body>
+</html>

+ 109 - 0
zheng-ui/zheng-cms-web/qa/tag/index.html

@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
+<head>
+    <meta charset="utf-8"/>
+    <title th:text="${tag.name} + ' - ZhengCms'">标签 - ZhengCms</title>
+    <meta name="keywords" content=""/>
+    <meta name="description" content=""/>
+    <meta name="renderer" content="webkit"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="shortcut icon" href="../../favicon.ico" th:href="@{${uiPath} + ${appName} + '/favicon.ico'}"/>
+    <link rel="stylesheet" href="../../css/bootstrap.min.css" th:href="@{${uiPath} + ${appName} + '/css/bootstrap.min.css'}"/>
+    <!--[if lt IE 9]>
+    <script src="../../js/vendor/html5shiv.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/html5shiv.js'}"></script>
+    <script src="../../js/vendor/respond.min.js" th:src="@{${uiPath} + ${appName} + '/js/vendor/respond.min.js'}"></script>
+    <![endif]-->
+    <script type="text/javascript">
+        if (/msie [6|7|8]/i.test(navigator.userAgent)) {};
+    </script>
+    <link rel="stylesheet" href="../../css/main.css" th:href="@{${uiPath} + ${appName} + '/css/main.css'}"/>
+</head>
+<body>
+<!-- .navbar -->
+<nav class="navbar navbar-inverse navbar-fixed-top"><!--navbar-inverse-->
+    <div class="container">
+        <!-- navbar-header -->
+        <div class="navbar-header">
+            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-menu">
+                <span class="sr-only">切换菜单</span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </button>
+            <a class="navbar-brand" href="../../index.html" th:href="@{/}" title="zhengCMS"><span id="logo-text-left">zheng</span><span id="logo-text-right">CMS</span></a>
+            <p class="navbar-text hidden-sm">最简约的内容管理系统</p>
+        </div>
+        <!-- /.navbar-header -->
+        <!-- navbar-collapse -->
+        <div class="collapse navbar-collapse" id="nav-menu">
+            <ul class="nav navbar-nav">
+                <li th:each="menu : ${menus}" th:if="${menu.pid} == null"><a th:href="@{${menu.url}}" th:target="${menu.target}" th:text="${menu.name}">菜单</a></li>
+            </ul>
+            <ul class="nav navbar-right navbar-nav">
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-search"></span></a>
+                    <ul class="dropdown-menu">
+                        <form id="search-form" class="form-inline">
+                            <div class="input-group">
+                                <input id="keywords" type="text" name="keywords" class="form-control" placeholder="搜索"/>
+                                <div class="input-group-btn">
+                                    <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
+                                </div>
+                            </div>
+                        </form>
+                    </ul>
+                </li>
+                <li><a href="login.html">登录</a></li>
+                <li><a href="reg.html">注册</a></li>
+                <li id="messages" class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-bell"></span>
+                        <span class="badge bg-important">5</span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/letter.html"><span class="glyphicon glyphicon-envelope"></span> 我的私信(<span class="msg-txt">1</span>)</a></li>
+                        <li><a href="home/message.html"><span class="glyphicon glyphicon-volume-up"></span> 系统消息(<span class="msg-txt">4</span>)</a></li>
+                    </ul>
+                </li>
+                <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        <span class="glyphicon glyphicon-user"></span>
+                        <span class="caret"></span>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li><a href="home/index.html"><span class="glyphicon glyphicon-home"></span> 个人博客</a></li>
+                        <li><a href="home/question.html"><span class="glyphicon glyphicon-question-sign"></span> 我的提问</a></li>
+                        <li><a href="home/answer.html"><span class="glyphicon glyphicon-ok-sign"></span> 我的回答</a></li>
+                        <li><a href="home/collection.html"><span class="glyphicon glyphicon-star"></span> 我的收藏</a></li>
+                        <li class="divider"></li>
+                        <li><a href="setting/info.html"><span class="glyphicon glyphicon-cog"></span> 修改资料</a></li>
+                        <li><a href="setting/password.html"><span class="glyphicon glyphicon-lock"></span> 密码安全</a></li>
+                        <li><a href="logout.html"><span class="glyphicon glyphicon-log-out"></span> 安全退出</a></li>
+                    </ul>
+                </li>
+            </ul>
+        </div>
+        <!-- /.navbar-collapse -->
+    </div>
+</nav>
+<!-- /.navbar -->
+<!-- .container -->
+<div class="container" style="padding-bottom:80px;">
+    <dl>
+        <dt><span th:text="${tag.name}">标签</span>问题列表</dt>
+        <dd th:each="article : ${articles}"><a href="../qa/question/index.html" th:href="@{'/qa/question/' + ${article.articleId}}" th:text="${article.title}">问题标题</a></dd>
+    </dl>
+    <div th:utext="${paginator.html}"></div>
+</div>
+<!-- /.container -->
+<!-- footer -->
+<footer class="container-fuild text-center" style="position:fixed;bottom:0;width:100%;background:#eee;padding:20px 0;">
+    Copyright &copy; 2017 ZhangShuzheng All Rights Reserved
+</footer>
+<!-- /footer -->
+<script src="../../js/jquery-1.11.2.min.js" th:src="@{${uiPath} + ${appName} + '/js/jquery-1.11.2.min.js'}"></script>
+<script src="../../js/bootstrap.min.js" th:src="@{${uiPath} + ${appName} + '/js/bootstrap.min.js'}"></script>
+<script src="../../js/main.js" th:src="@{${uiPath} + ${appName} + '/js/main.js'}"></script>
+</body>
+</html>

+ 1 - 1
zheng-ui/zheng-cms-web/search/index.html

@@ -92,7 +92,7 @@
 <div class="container" style="padding-bottom:80px;">
     <dl>
         <dt>搜索结果</dt>
-        <dd th:each="article : ${articles}"><a href="../article/index.html" th:href="@{'/article/' + ${article.articleId}}" th:text="${article.title}">文章标题</a></dd>
+        <dd th:each="article : ${articles}"><a href="../news/article/index.html" th:href="@{'/article/' + ${article.articleId}}" th:text="${article.title}">文章标题</a></dd>
     </dl>
     <div th:utext="${paginator.html}"></div>
 </div>

+ 1 - 0
zheng-upms/zheng-upms-rpc-api/src/main/java/com/zheng/upms/rpc/api/UpmsUserService.java

@@ -10,4 +10,5 @@ import com.zheng.upms.dao.model.UpmsUserExample;
 */
 public interface UpmsUserService extends BaseService<UpmsUser, UpmsUserExample> {
 
+    UpmsUser insert2(UpmsUser upmsUser);
 }

+ 4 - 0
zheng-upms/zheng-upms-rpc-api/src/main/java/com/zheng/upms/rpc/api/UpmsUserServiceMock.java

@@ -11,4 +11,8 @@ import com.zheng.upms.dao.model.UpmsUserExample;
 */
 public class UpmsUserServiceMock extends BaseServiceMock<UpmsUserMapper, UpmsUser, UpmsUserExample> implements UpmsUserService {
 
+    @Override
+    public UpmsUser insert2(UpmsUser upmsUser) {
+        return null;
+    }
 }

+ 5 - 0
zheng-upms/zheng-upms-rpc-service/src/main/java/com/zheng/upms/rpc/service/impl/UpmsUserServiceImpl.java

@@ -26,4 +26,9 @@ public class UpmsUserServiceImpl extends BaseServiceImpl<UpmsUserMapper, UpmsUse
     @Autowired
     UpmsUserMapper upmsUserMapper;
 
+    @Override
+    public UpmsUser insert2(UpmsUser upmsUser) {
+        upmsUserMapper.insert(upmsUser);
+        return upmsUser;
+    }
 }

+ 22 - 2
zheng-upms/zheng-upms-rpc-service/src/test/java/com/zheng/upms/rpc/service/UpmsServiceTest.java

@@ -1,7 +1,10 @@
 package com.zheng.upms.rpc.service;
 
+import com.zheng.upms.dao.mapper.UpmsUserMapper;
 import com.zheng.upms.dao.model.UpmsSystemExample;
+import com.zheng.upms.dao.model.UpmsUser;
 import com.zheng.upms.rpc.api.UpmsSystemService;
+import com.zheng.upms.rpc.api.UpmsUserService;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -25,10 +28,27 @@ public class UpmsServiceTest {
     @Autowired
     private UpmsSystemService upmsSystemService;
 
+    @Autowired
+    private UpmsUserMapper upmsUserMapper;
+
+    @Autowired
+    private UpmsUserService upmsUserService;
+
     @Test
     public void index() {
-        int count = upmsSystemService.countByExample(new UpmsSystemExample());
-        System.out.println(count);
+        UpmsUser upmsUser = new UpmsUser();
+        upmsUser.setAvatar("");
+        upmsUser.setCtime(System.currentTimeMillis());
+        upmsUser.setEmail("");
+        upmsUser.setLocked((byte) 0);
+        upmsUser.setPassword("xxx");
+        upmsUser.setPhone("");
+        upmsUser.setRealname("zsz");
+        upmsUser.setSex((byte) 1);
+        upmsUser.setSalt("");
+        upmsUser.setUsername("zsz");
+        upmsUserService.insertSelective(upmsUser);
+        System.out.println(upmsUser.getUserId());
     }
 
 }

+ 1 - 0
zheng-upms/zheng-upms-server/src/main/java/com/zheng/upms/server/controller/manage/UpmsUserController.java

@@ -241,6 +241,7 @@ public class UpmsUserController extends BaseController {
         upmsUser.setPassword(MD5Util.MD5(upmsUser.getPassword() + upmsUser.getSalt()));
         upmsUser.setCtime(time);
         int count = upmsUserService.insertSelective(upmsUser);
+        upmsUser = upmsUserService.insert2(upmsUser);
         _log.info("新增用户,主键:userId={}", upmsUser.getUserId());
         return new UpmsResult(UpmsResultConstant.SUCCESS, count);
     }