ms-dev 6 rokov pred
rodič
commit
3dc5625a7a

+ 26 - 4
pom.xml

@@ -31,10 +31,32 @@
 			<classifier>classes</classifier>
 			<scope>provided</scope>
 		</dependency>
-		<!-- <dependency> <groupId>net.mingsoft</groupId> <artifactId>ms-mdiy</artifactId> 
-			<version>1.0.7-SNAPSHOT</version> <type>war</type> </dependency> <dependency> 
-			<groupId>net.mingsoft</groupId> <artifactId>ms-mdiy</artifactId> <version>1.0.7-SNAPSHOT</version> 
-			<classifier>classes</classifier> <scope>provided</scope> </dependency> -->
+		<dependency>
+			<groupId>net.mingsoft</groupId>
+			<artifactId>ms-mdiy</artifactId>
+			<version>1.0.7-SNAPSHOT</version>
+			<type>war</type>
+		</dependency>
+		<dependency>
+			<groupId>net.mingsoft</groupId>
+			<artifactId>ms-mdiy</artifactId>
+			<version>1.0.7-SNAPSHOT</version>
+			<classifier>classes</classifier>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>net.mingsoft</groupId>
+			<artifactId>ms-mpeople</artifactId>
+			<version>1.0.7-SNAPSHOT</version>
+			<type>war</type>
+		</dependency>
+		<dependency>
+			<groupId>net.mingsoft</groupId>
+			<artifactId>ms-mpeople</artifactId>
+			<version>1.0.7-SNAPSHOT</version>
+			<classifier>classes</classifier>
+			<scope>provided</scope>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 633 - 0
src/main/java/net/mingsoft/cms/action/ArticleAction.java

@@ -0,0 +1,633 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.action;
+
+import java.io.File;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import com.alibaba.fastjson.JSONArray;
+
+import net.mingsoft.base.entity.BaseEntity;
+import net.mingsoft.base.filter.DateValueFilter;
+import net.mingsoft.base.filter.DoubleValueFilter;
+import net.mingsoft.basic.action.BaseAction;
+import net.mingsoft.basic.bean.EUListBean;
+import net.mingsoft.basic.biz.IColumnBiz;
+import net.mingsoft.basic.entity.ColumnEntity;
+import net.mingsoft.basic.util.ArrysUtil;
+import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.basic.util.FileUtil;
+import net.mingsoft.basic.util.StringUtil;
+import net.mingsoft.cms.biz.IArticleBiz;
+import net.mingsoft.cms.constant.ModelCode;
+import net.mingsoft.cms.constant.e.ColumnTypeEnum;
+import net.mingsoft.cms.entity.ArticleEntity;
+import net.mingsoft.mdiy.biz.IContentModelBiz;
+import net.mingsoft.mdiy.biz.IContentModelFieldBiz;
+import net.mingsoft.mdiy.entity.ContentModelEntity;
+import net.mingsoft.mdiy.entity.ContentModelFieldEntity;
+import net.mingsoft.mdiy.util.DictUtil;
+import net.mingsoft.mdiy.util.ParserUtil;
+
+/**
+ * @ClassName:  ArticleAction   
+ * @Description:TODO 文章管理   
+ * @author: 铭飞开发团队
+ * @date:   2018年1月31日 下午2:51:39   
+ *     
+ * @Copyright: 2018 www.mingsoft.net Inc. All rights reserved.
+ */
+@Controller
+@RequestMapping("/${ms.manager.path}/cms/article")
+public class ArticleAction extends BaseAction {
+	
+	/**
+	 * 上传路径
+	 */
+	@Value("${ms.upload.path}")
+	private String uploadFloderPath;
+	
+	/**
+	 * 业务层的注入
+	 */
+	@Autowired
+	private IColumnBiz columnBiz;
+
+	/**
+	 * 文章管理业务处理层
+	 */
+	@Autowired
+	private IArticleBiz articleBiz;
+
+	/**
+	 * 字段管理业务层
+	 */
+	@Autowired
+	private IContentModelFieldBiz fieldBiz;
+
+	/**
+	 * 内容管理业务层
+	 */
+	@Autowired
+	private IContentModelBiz contentBiz;
+
+	/**
+	 * 判断是否为checkbox类型
+	 */
+	private static final int checkBox = 11;
+
+
+	/**
+	 * 加载页面显示所有文章信息
+	 * 
+	 * @param request
+	 * @return 返回文章页面显示地址
+	 */
+	@SuppressWarnings("static-access")
+	@RequestMapping("/index")
+	public String index(HttpServletRequest request, ModelMap mode, HttpServletResponse response) {
+		// 获取站点id
+		int appId = BasicUtil.getAppId();
+		List<ColumnEntity> list = columnBiz.queryAll(appId, this.getModelCodeId(request, ModelCode.CMS_COLUMN));
+		request.setAttribute("listColumn", JSONArray.toJSONString(list));
+		// 返回路径
+		return view("/cms/article/index"); // 这里表示显示/manager/cms/article/article_list.ftl
+	}
+
+	/**
+	 * 返回一个文章列表框架和一些基础数据
+	 * @param article
+	 * @param request
+	 * @param mode
+	 * @param response
+	 * @param categoryId
+	 * @return 返回一个文章列表界面
+	 */
+	@RequestMapping("/{categoryId}/main")
+	public String main(@ModelAttribute ArticleEntity article, HttpServletRequest request, ModelMap mode,
+			HttpServletResponse response, @PathVariable int categoryId) {
+		String articleType = request.getParameter("articleType");
+		String isParent = BasicUtil.getString("isParent", "false");
+		mode.addAttribute("isParent", isParent);
+		//使用糊涂工具排序使全部属性排在第一个
+		mode.addAttribute("articleTypeList", DictUtil.list("文章属性"));
+		mode.addAttribute("articleType", articleType);
+ 		mode.addAttribute("categoryId", categoryId);
+		//返回文章页面显示地址
+		return view("/cms/article/article_main");
+	}
+	
+	/**
+	 * 加载页面显示所有文章信息
+	 * 
+	 * @param request
+	 * @return 返回文章页面显示数据
+	 */
+	@RequestMapping("/{categoryId}/list")
+	public void list(@ModelAttribute ArticleEntity article, HttpServletRequest request, ModelMap mode,
+			HttpServletResponse response, @PathVariable int categoryId) {
+		int[] basicCategoryIds = null;
+		String articleType = article.getArticleType();
+		if(StringUtils.isEmpty(articleType)){
+			articleType = BasicUtil.getString("articleTypeStr");
+		}
+		if(!StringUtils.isEmpty(articleType) && articleType.equals("a")){
+			articleType = null;
+		}
+		if(categoryId > 0){
+			 basicCategoryIds = columnBiz.queryChildrenCategoryIds(categoryId, BasicUtil.getAppId(),
+					BasicUtil.getModelCodeId(ModelCode.CMS_COLUMN));
+		}
+		int appId = BasicUtil.getAppId();
+		BasicUtil.startPage();
+		article.setBasicDisplay(-1);
+		//查询文章列表
+		List<ArticleEntity> articleList = articleBiz.query(appId, basicCategoryIds, articleType, null, null, true, null, null, article);
+		EUListBean _list = new EUListBean(articleList, (int) BasicUtil.endPage(articleList).getTotal());
+		//将数据以json数据的形式返回
+		this.outJson(response, net.mingsoft.base.util.JSONArray.toJSONString(_list, new DoubleValueFilter(),new DateValueFilter("yyyy-MM-dd")));
+		
+	}
+
+	/**
+	 * 添加文章页面
+	 * 
+	 * @return 保存文章的页面地址
+	 */
+	@SuppressWarnings("static-access")
+	@RequestMapping("/add")
+	public String add(ModelMap mode, HttpServletRequest request) {
+		int categoryId = BasicUtil.getInt("categoryId", 0);
+		String categoryTitle = request.getParameter("categoryTitle");
+		// 文章属性
+		mode.addAttribute("articleType", DictUtil.list("文章属性"));
+		// 站点ID
+		int appId = BasicUtil.getAppId();
+		List<ColumnEntity> list = columnBiz.queryAll(appId, this.getModelCodeId(request, ModelCode.CMS_COLUMN));
+		mode.addAttribute("appId", appId);
+		mode.addAttribute("listColumn", JSONArray.toJSONString(list));
+		boolean isEditCategory = false; // 新增,不是单篇
+		int columnType=1;//新增,不是单篇
+		if(categoryId != 0){
+			// 获取栏目id
+			ColumnEntity column = (ColumnEntity) columnBiz.getEntity(categoryId);
+			columnType = column.getColumnType();
+			// 判断栏目是否为"",如果是"",就重新赋值
+			if (StringUtils.isBlank(categoryTitle)) {
+				categoryTitle = column.getCategoryTitle();
+			}
+			// 判断栏目是否是单篇
+			if (column != null && column.getColumnType() == ColumnTypeEnum.COLUMN_TYPE_COVER.toInt()) {
+				isEditCategory = true; // 是单页
+				columnType = column.getColumnType();;
+			}
+		}
+		mode.addAttribute("categoryTitle", categoryTitle);
+		mode.addAttribute("isEditCategory", isEditCategory); // 新增状态
+		mode.addAttribute("columnType", columnType);
+		mode.addAttribute("categoryId", categoryId);
+		mode.addAttribute("articleImagesUrl", uploadFloderPath+net.mingsoft.base.constant.Const.SEPARATOR
+				+BasicUtil.getAppId()+net.mingsoft.base.constant.Const.SEPARATOR);
+		// 添加一个空的article实体
+		ArticleEntity article = new ArticleEntity();
+		mode.addAttribute("article", article);
+		// 返回路径
+		return view("/cms/article/article_form"); // 这里表示显示/manager/cms/article/article_save.ftl
+	}
+
+	/**
+	 * 获取表单信息进行保存
+	 * 
+	 * @param article
+	 *            文章对象
+	 */
+	@RequestMapping("/save")
+	@RequiresPermissions("article:save")
+	public void save(@ModelAttribute ArticleEntity article, HttpServletRequest request, HttpServletResponse response) {
+		// 获取站点id
+		int appId = BasicUtil.getAppId();
+		// 验证文章,文章自由排序,栏目id
+		if (!validateForm(article, response)) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false);
+
+		}
+		 
+		article.setBasicUpdateTime(new Timestamp(System.currentTimeMillis()));
+		// 文章类型
+		String langtyp[] = request.getParameterValues("articleType");
+		if (langtyp != null) {
+			StringBuffer sb = new StringBuffer();
+			for (int j = 0; j < langtyp.length; j++) {
+				sb.append(langtyp[j] + ",");
+			}
+		}
+		String checkboxType = BasicUtil.getString("checkboxType");
+		//如果选择一个属性不做排序操作
+		if(!StringUtils.isEmpty(checkboxType) && checkboxType.length()>2){
+			// 文章类型排序
+			article.setArticleType(ArrysUtil.sort(checkboxType, ",")+",");
+		}else{
+			article.setArticleType(checkboxType);
+		}
+		// 问题:由于上传的图片路径后面可能带有|符合。所以要进行将“|”替换空
+		// 空值判断
+		if (!StringUtils.isBlank(article.getBasicThumbnails())) {
+			article.setBasicThumbnails(article.getBasicThumbnails().replace("|", ""));
+		}
+		ColumnEntity column = (ColumnEntity) columnBiz.getEntity(article.getBasicCategoryId());
+		article.setColumn(column);
+		
+		// 添加文章所属的站点id
+		article.setArticleWebId(appId);
+		// 绑定模块编号
+		article.setBasicModelId(BasicUtil.getInt("modelId"));
+		// 保存文章实体
+
+		articleBiz.saveBasic(article);
+		if (column.getColumnType() == ColumnTypeEnum.COLUMN_TYPE_LIST.toInt()) {// 列表
+			article.setArticleUrl(column.getColumnPath() + File.separator + article.getBasicId() + ParserUtil.HTML_SUFFIX);
+		} else if (column.getColumnType() == ColumnTypeEnum.COLUMN_TYPE_COVER.toInt()) {// 单篇
+			article.setArticleUrl(column.getColumnPath() + File.separator + ParserUtil.INDEX+ParserUtil.HTML_SUFFIX);
+		}
+		articleBiz.updateBasic(article);
+
+		// 判断栏目是否存在新增字段
+		if (column.getColumnContentModelId() != 0) {
+			// 保存所有的字段信息
+			List<BaseEntity> listField = fieldBiz.queryListByCmid(column.getColumnContentModelId());
+			// 获取内容模型实体
+			ContentModelEntity contentModel = (ContentModelEntity) contentBiz
+					.getEntity(column.getColumnContentModelId());
+			if (contentModel != null) {
+				// 保存新增字段的信息
+				Map param = this.checkField(listField, request, article.getBasicId());
+				fieldBiz.insertBySQL(contentModel.getCmTableName(), param);
+			}
+
+		}
+
+		//
+
+		if (article.getColumn().getColumnType() == ColumnTypeEnum.COLUMN_TYPE_COVER.toInt()) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, true, "" + article.getColumn().getCategoryId(), article.getBasicId());
+		} else {
+			this.outJson(response, ModelCode.CMS_ARTICLE, true, article.getColumn().getCategoryId()+"", "");
+		}
+	}
+
+	/**
+	 * 验证表单
+	 * 
+	 * @param article
+	 * @param response
+	 * @return 返回Boolean类型 true:通过,false:有错
+	 */
+	public boolean validateForm(ArticleEntity article, HttpServletResponse response) {
+		// 对表单数据进行再次验证
+		// 验证文章标题是否为空
+		if (StringUtils.isBlank(article.getBasicTitle())) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false,
+					getResString("err.empty", this.getResString("basicTitle")));
+			return false;
+		}
+		// 验证文章所属是否为0
+		if (article.getBasicCategoryId() == 0) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false,
+					getResString("err.empty", this.getResString("basicCategoryId")));
+			return false;
+		}
+		// 验证文章标题长度,若超过定义长度则截取
+		if (!StringUtil.checkLength(article.getBasicTitle(), 1, 300)) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false,
+					getResString("err.length", this.getResString("basicTitle"), "1", "300"));
+			return false;
+		}
+		// 验证文章来源长度,若超过定义长度则截取
+		if (!StringUtils.isBlank(article.getArticleSource())
+				&& !StringUtil.checkLength(article.getArticleSource(), 1, 300)) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false,
+					getResString("err.length", this.getResString("articleSource"), "1", "300"));
+			return false;
+		}
+		// 验证文章作者长度,若超过定义长度则截取
+		if (!StringUtils.isBlank(article.getArticleAuthor())
+				&& !StringUtil.checkLength(article.getArticleAuthor(), 1, 12)) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false,
+					getResString("err.length", this.getResString("articleAuthor"), "1", "12"));
+			return false;
+		}
+		// 验证文章描述长度,若超过定义长度则截取
+		if (!StringUtils.isBlank(article.getBasicDescription())
+				&& !StringUtil.checkLength(article.getBasicDescription(), 1, 400)) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false,
+					getResString("err.length", this.getResString("basicDescription"), "1", "400"));
+			return false;
+		}
+		// 验证文章关键字长度,若超过定义长度则截取
+		if (!StringUtils.isBlank(article.getArticleKeyword())
+				&& !StringUtil.checkLength(article.getArticleKeyword(), 1, 155)) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false,
+					getResString("err.length", this.getResString("articleKeyword"), "1", "155"));
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * 更新文章
+	 * 
+	 * @param basicId
+	 *            文章id
+	 * @param article
+	 *            文章实体
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/{basicId}/update")
+	@RequiresPermissions("article:update")
+	public void update(@PathVariable int basicId, @ModelAttribute ArticleEntity article, HttpServletRequest request,
+			HttpServletResponse response) {
+		// 获取站点id
+		int appId = BasicUtil.getAppId();
+		article.setBasicUpdateTime(new Timestamp(System.currentTimeMillis()));
+		// 文章类型
+		String checkboxType = BasicUtil.getString("checkboxType");
+		//如果选择一个属性不做排序操作
+		if(!StringUtils.isEmpty(checkboxType) && checkboxType.length()>2){
+			// 文章类型排序
+			article.setArticleType(ArrysUtil.sort(checkboxType, ",")+",");
+		}else{
+			article.setArticleType(checkboxType);
+		}
+		// 问题:由于上传的图片路径后面可能带有|符合。所以要进行将“|”替换空
+		// 空值判断
+		if (!StringUtils.isBlank(article.getBasicThumbnails())) {
+			article.setBasicThumbnails(article.getBasicThumbnails().replace("|", ""));
+		}
+		// 获取更改前的文章实体
+		ArticleEntity oldArticle = (ArticleEntity) articleBiz.getEntity(basicId);
+		// 获取栏目实体
+		ColumnEntity column = (ColumnEntity) columnBiz.getEntity(article.getBasicCategoryId());
+		if (oldArticle != null) {
+			// 获取更改前的文章所属栏目实体
+			ColumnEntity oldColumn = (ColumnEntity) columnBiz.getEntity(oldArticle.getBasicCategoryId());
+
+			// 通过表单类型id判断是否更改了表单类型,如果更改则先删除记录
+			if (oldColumn.getColumnContentModelId() != column.getColumnContentModelId()) {
+				// 获取旧的内容模型id
+				ContentModelEntity contentModel = (ContentModelEntity) contentBiz
+						.getEntity(oldColumn.getColumnContentModelId());
+				// 删除旧的内容模型中保存的值
+				Map wheres = new HashMap();
+				wheres.put("basicId", article.getBasicId());
+				if (contentModel != null) {
+					fieldBiz.deleteBySQL(contentModel.getCmTableName(), wheres);
+				}
+				// 判断栏目是否存在新增字段
+				if (column.getColumnContentModelId() != 0) {
+					// 保存所有的字段信息
+					List<BaseEntity> listField = fieldBiz.queryListByCmid(column.getColumnContentModelId());
+					ContentModelEntity newContentModel = (ContentModelEntity) contentBiz
+							.getEntity(column.getColumnContentModelId());
+					if (newContentModel != null) {
+						Map param = this.checkField(listField, request, article.getBasicId());
+						fieldBiz.insertBySQL(newContentModel.getCmTableName(), param);
+					}
+				}
+			}
+		}
+
+		// 添加文章所属的站点id
+		article.setArticleWebId(appId);
+		// 设置文章所属的栏目实体
+		article.setColumn(column);
+
+		article.setBasicUpdateTime(new Date());
+
+		String articleType = request.getParameter("articleTypeJson");
+		articleBiz.updateBasic(article);
+
+		// 判断该文章是否存在新增字段
+		if (column.getColumnContentModelId() != 0) {
+			// 保存所有的字段信息
+			List<BaseEntity> listField = fieldBiz.queryListByCmid(column.getColumnContentModelId());
+			// // update中的where条件
+			Map where = new HashMap();
+			// 压入默认的basicId字段
+			where.put("basicId", article.getBasicId());
+			// 遍历字段的信息
+			Map param = this.checkField(listField, request, article.getBasicId());
+			ContentModelEntity contentModel = (ContentModelEntity) contentBiz
+					.getEntity(column.getColumnContentModelId());
+			if (contentModel != null) {
+				// 遍历所有的字段实体,得到字段名列表信息
+				List<String> listFieldName = new ArrayList<String>();
+				listFieldName.add("basicId");
+				// 查询新增字段的信息
+				List fieldLists = fieldBiz.queryBySQL(contentModel.getCmTableName(), listFieldName, where);
+
+				// 判断新增字段表中是否存在该文章,不存在则保存,否则更新
+				if (fieldLists == null || fieldLists.size() == 0) {
+					fieldBiz.insertBySQL(contentModel.getCmTableName(), param);
+				} else {
+					fieldBiz.updateBySQL(contentModel.getCmTableName(), param, where);
+				}
+
+			}
+		}
+
+		switch (column.getColumnType()) {
+		case ColumnEntity.COLUMN_TYPE_COVER:
+			this.outJson(response, ModelCode.CMS_ARTICLE, true, column.getCategoryId() + "", "");
+			break;
+		case ColumnEntity.COLUMN_TYPE_LIST:
+			this.outJson(response, ModelCode.CMS_ARTICLE, true, column.getCategoryId() + "",
+					this.redirectBack(request, false));
+		}
+
+	}
+
+	/**
+	 * 显示更新内容
+	 * 
+	 * @param request
+	 * @return 修改文章的页面地址
+	 */
+	@RequestMapping("/{id}/edit")
+	public String edit(@PathVariable int id, ModelMap model, HttpServletRequest request) {
+
+		// 如果_categoryId大于0表示是编辑封面栏目,应该先查询分类下面的唯一一篇文章
+		String categoryTitle = request.getParameter("categoryTitle");
+		// 板块id
+		int categoryId = BasicUtil.getInt("categoryId", 0);
+		ArticleEntity articleEntity = null;
+		int appId = BasicUtil.getAppId();
+		model.addAttribute("appId", appId);
+		model.addAttribute("articleImagesUrl", "/upload/"+BasicUtil.getAppId()+"/");
+		if (categoryId > 0) { // 分类获取文章
+			articleEntity = articleBiz.getByCategoryId(categoryId);
+			ColumnEntity column = articleEntity.getColumn();
+			int columnType = column.getColumnType();
+			model.addAttribute("article", articleEntity);
+			// 文章属性
+			model.addAttribute("articleType", DictUtil.list("文章属性"));
+			model.addAttribute("categoryTitle", categoryTitle);
+			model.addAttribute("categoryId", categoryId);// 编辑封面
+			model.addAttribute("isEditCategory", true);// 编辑封面
+			model.addAttribute("columnType", columnType);
+			return view("/cms/article/article_form");
+		} else if (id > 0) { // 文章id获取
+			// 允许编辑文章时更改分类
+			List<ColumnEntity> list = columnBiz.queryAll(appId, this.getModelCodeId(request, ModelCode.CMS_COLUMN));
+			@SuppressWarnings("static-access")
+			String listJsonString = JSONArray.toJSONString(list);
+			request.setAttribute("listColumn", listJsonString);
+			// 文章属性
+			model.addAttribute("articleType", DictUtil.list("文章属性"));
+
+			articleEntity = (ArticleEntity) articleBiz.getEntity(id);
+			model.addAttribute("article", articleEntity);
+			// 判断是否是封面类型的栏目,如果是封面类型的栏目有些信息需要屏蔽,例如分类
+			ColumnEntity column = articleEntity.getColumn();
+			int columnType = column.getColumnType();
+			if (column.getColumnType() == ColumnEntity.COLUMN_TYPE_COVER) {
+				model.addAttribute("categoryTitle", categoryTitle);
+				model.addAttribute("categoryId", column.getCategoryId());// 编辑封面
+				model.addAttribute("isEditCategory", true);// 编辑封面
+			} else {
+				model.addAttribute("categoryTitle", articleEntity.getColumn().getCategoryTitle());
+				model.addAttribute("isEditCategory", false);// 编辑文章
+			}
+			model.addAttribute("columnType", columnType);
+			model.addAttribute("categoryId", column.getCategoryId());// 编辑封面
+			return view("/cms/article/article_form");
+		} else {// 非法
+			// return view("/cms/article/article_form");
+			return this.redirectBack(request, true);
+		}
+	}
+
+	/**
+	 * 删除文章
+	 * 
+	 * @param request
+	 * @param response
+	 * @return
+	 */
+	@RequestMapping("/delete")
+	@RequiresPermissions("article:del")
+	public void delete(@RequestBody List<ArticleEntity> articles, HttpServletRequest request, HttpServletResponse response) {
+		int appId = BasicUtil.getAppId();
+		int[] ids = new int[articles.size()];
+		//循环获取id数据
+		for(int i=0;i<articles.size();i++){
+			ids[i] = articles.get(i).getArticleID();
+		}
+		
+		if (ids.length == 0 || ids == null) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false, "", this.redirectBack(request, false));
+			return;
+		}
+		// 删除多个帖子
+		articleBiz.deleteBasic(ids);
+		FileUtil.del(articles);
+		this.outJson(response, ModelCode.CMS_ARTICLE, true, "", this.redirectBack(request, false));
+	}
+
+	/**
+	 * 遍历出所有文章新增字段的信息
+	 * 
+	 * @param listField
+	 *            :字段列表
+	 * @param request
+	 * @param articleId
+	 *            文章id
+	 * @return 字段信息
+	 */
+	private Map checkField(List<BaseEntity> listField, HttpServletRequest request, int articleId) {
+		Map mapParams = new HashMap();
+		// 压入默认的basicId字段
+		mapParams.put("basicId", articleId);
+		// 遍历字段名
+		for (int i = 0; i < listField.size(); i++) {
+			ContentModelFieldEntity field = (ContentModelFieldEntity) listField.get(i);
+			String fieldName = field.getFieldFieldName();
+			// 判断字段类型是否为checkbox类型
+			if (field.getFieldType() == checkBox) {
+				String langtyp[] = request.getParameterValues(field.getFieldFieldName());
+				if (langtyp != null) {
+					StringBuffer sb = new StringBuffer();
+					for (int j = 0; j < langtyp.length; j++) {
+						sb.append(langtyp[j] + ",");
+					}
+					mapParams.put(field.getFieldFieldName(), sb.toString());
+				} else {
+					mapParams.put(field.getFieldFieldName(), langtyp);
+				}
+			} else {
+				if (StringUtils.isBlank(request.getParameter(field.getFieldFieldName()))) {
+					mapParams.put(field.getFieldFieldName(), null);
+				} else {
+					mapParams.put(field.getFieldFieldName(), request.getParameter(field.getFieldFieldName()));
+				}
+			}
+		}
+		return mapParams;
+	}
+
+	/**
+	 * 查询单页栏目是否绑定了文章
+	 * 
+	 * @param article
+	 *            文章对象
+	 */
+	@RequestMapping("/{id}/queryColumnArticle")
+	public void queryColumnArticle(@PathVariable int id, HttpServletResponse response) {
+		List articls = articleBiz.queryListByColumnId(id);
+		if (articls == null || articls.size() == 0) {
+			this.outJson(response, ModelCode.CMS_ARTICLE, true, null);
+		} else {
+			this.outJson(response, ModelCode.CMS_ARTICLE, false, null);
+		}
+	}
+
+	
+}

+ 295 - 0
src/main/java/net/mingsoft/cms/action/ColumnAction.java

@@ -0,0 +1,295 @@
+package net.mingsoft.cms.action;
+
+
+import java.io.File;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.alibaba.fastjson.JSONArray;
+import net.mingsoft.basic.action.BaseAction;
+import net.mingsoft.basic.biz.ICategoryBiz;
+import net.mingsoft.basic.biz.IColumnBiz;
+import net.mingsoft.basic.biz.IModelBiz;
+import net.mingsoft.basic.constant.Const;
+import net.mingsoft.basic.constant.ModelCode;
+import net.mingsoft.basic.constant.e.SessionConstEnum;
+import net.mingsoft.basic.entity.ColumnEntity;
+import net.mingsoft.basic.entity.ManagerEntity;
+
+import net.mingsoft.basic.bean.EUListBean;
+import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.basic.util.FileUtil;
+import net.mingsoft.basic.util.StringUtil;
+import net.mingsoft.mdiy.util.ParserUtil;
+
+
+
+/**
+ * 铭飞MS平台,通用栏目分类,为了区分文章栏目与其他栏目的权限,该类是从basic模块复制过来
+ * @author 铭飞开发团队
+ * @version 
+ * 版本号:100-000-000<br/>
+ * 创建日期:2017年8月9日<br/>
+ * 历史修订:<br/>
+ */
+@Controller("articleColumnAction")
+@RequestMapping("/${ms.manager.path}/cms/column")
+public class ColumnAction extends BaseAction{
+	
+	
+	/**
+	 * 栏目业务层
+	 */
+	@Autowired
+	private IColumnBiz columnBiz;
+	@Autowired
+	private ICategoryBiz categoryBiz;
+	
+	/**
+	 * 模块业务层注入
+	 */
+	@Autowired
+	private IModelBiz modelBiz;
+	/**
+	 * 返回主界面index
+	 */
+	@RequestMapping("/index")
+	@RequiresPermissions("cms:column:view")
+	public String index(HttpServletResponse response,HttpServletRequest request,ModelMap model){
+		model.addAttribute("model", "cms");
+		return view ("/column/index");
+	}
+	/**
+	 * 栏目添加跳转页面
+	 * 
+	 * @return
+	 */
+	@RequestMapping("/add")
+	public String add(HttpServletRequest request,ModelMap model) {
+		ManagerEntity managerSession = (ManagerEntity) getSession(request, SessionConstEnum.MANAGER_SESSION);
+		// 站点ID
+		int appId =this.getAppId(request);
+		List<ColumnEntity> list = columnBiz.queryAll(appId, this.getModelCodeId(request));
+		ColumnEntity columnSuper = new ColumnEntity();
+		model.addAttribute("appId",appId);
+		model.addAttribute("columnSuper", columnSuper);
+		model.addAttribute("column",new ColumnEntity());
+		model.addAttribute("listColumn", JSONArray.toJSONString(list));
+		model.addAttribute("model", "cms");
+		return view("/column/form");
+	}
+
+	/**
+	 * 后台验证填写的栏目信息是否合法
+	 * @param column  栏目信息
+	 * @param response
+	 * @return false:不合法 true:合法
+	 */
+	private boolean checkForm(ColumnEntity column, HttpServletResponse response){
+		//栏目标题空值验证
+		if(StringUtils.isBlank(column.getCategoryTitle())){
+			this.outJson( response, ModelCode.COLUMN, false, getResString("err.empty", this.getResString("categoryTitle")));
+			return false;
+		}
+		//栏目标题长度验证
+		if(!StringUtil.checkLength(column.getCategoryTitle(), 1, 31)){
+			this.outJson( response, ModelCode.COLUMN, false, getResString("err.length", this.getResString("categoryTitle"), "1", "30"));
+			return false;
+		}
+		//栏目属性空值验证
+		if(StringUtils.isBlank(column.getColumnType()+"")){
+			this.outJson( response, ModelCode.COLUMN, false, getResString("err.empty", this.getResString("columnType")));
+			return false;
+		}
+		
+		return true;
+	}
+
+	/**
+	 * 组织栏目链接地址
+	 * @param request
+	 * @param column 栏目实体
+	 */
+	private void columnPath(HttpServletRequest request,ColumnEntity column){
+		StringBuffer columnPath = new StringBuffer();
+		String file = this.getRealPath(request,null)+ParserUtil.HTML+File.separator+ column.getAppId();
+		String delFile = "";
+		//修改栏目路径时,删除已存在的文件夹
+		column = (ColumnEntity) columnBiz.getEntity(column.getCategoryId());
+		delFile = file + column.getColumnPath();
+		if(!StringUtils.isBlank(delFile)){
+			File delFileName = new File(delFile);
+			delFileName.delete();
+		}
+		//若为顶级栏目,则路径为:/+栏目ID
+		if(column.getCategoryCategoryId() == 0){
+			column.setColumnPath(File.separator+column.getCategoryId());
+			file = file + File.separator + column.getCategoryId();
+		} else {
+			List<ColumnEntity> list = columnBiz.queryParentColumnByColumnId(column.getCategoryId());
+			if(list != null){
+				StringBuffer temp = new StringBuffer();
+				for(int i = list.size()-1; i>=0; i--){
+					ColumnEntity entity = list.get(i);
+					columnPath.append(File.separator).append(entity.getCategoryId());
+					temp.append(File.separator).append(entity.getCategoryId());
+				}
+				column.setColumnPath(columnPath.append(File.separator).append(column.getCategoryId()).toString());
+				file = file + temp.toString() + File.separator + column.getCategoryId();
+			}
+		}
+		columnBiz.updateEntity(column);
+		//生成文件夹
+		File fileName = new File(file);
+        fileName.mkdir();
+	}
+	
+	/**
+	 * @param column 栏目表实体
+	 * <i>column参数包含字段信息参考:</i><br/>
+	 * columnCategoryid:多个columnCategoryid直接用逗号隔开,例如columnCategoryid=1,2,3,4
+	 * 批量删除栏目表
+	 *            <dt><span class="strong">返回</span></dt><br/>
+	 *            <dd>{code:"错误编码",<br/>
+	 *            result:"true|false",<br/>
+	 *            resultMsg:"错误信息"<br/>
+	 *            }</dd>
+	 */
+	@RequestMapping("/delete")
+	@ResponseBody
+	public void delete(HttpServletResponse response, HttpServletRequest request) {
+		int[] ids = BasicUtil.getInts("ids", ",");
+		ColumnEntity column =new ColumnEntity();
+		for(int i=0;i<ids.length;i++){
+			column = (ColumnEntity) columnBiz.getEntity(ids[i]);
+			columnBiz.deleteCategory(ids[i]);
+			FileUtil.del(column);
+		};
+		this.outJson(response, true);
+	}
+		
+	/**
+	 * 栏目更新页面跳转
+	 * @param columnId 栏目ID
+	 * @param request
+	 * @param model
+	 * @return 编辑栏目页
+	 */
+	@RequestMapping("/{columnId}/edit")
+	public String edit(@PathVariable int columnId, HttpServletRequest request,ModelMap model) {
+		// 获取管理实体
+		ManagerEntity managerSession = (ManagerEntity) getSession(request, SessionConstEnum.MANAGER_SESSION);
+		// 站点ID
+		int appId = this.getAppId(request);
+		List<ColumnEntity> list = new ArrayList<ColumnEntity>();
+		// 判断管理员权限,查询其管理的栏目集合
+		list = columnBiz.queryAll(appId, this.getModelCodeId(request));
+		//查询当前栏目实体
+		ColumnEntity column = (ColumnEntity) columnBiz.getEntity(columnId);
+		model.addAttribute("appId",appId);
+		model.addAttribute("column", column);
+		model.addAttribute("columnc", column.getCategoryId());
+		ColumnEntity columnSuper = new ColumnEntity();
+		// 获取父栏目对象
+		if (column.getCategoryCategoryId() != Const.COLUMN_TOP_CATEGORY_ID) {
+			columnSuper = (ColumnEntity) columnBiz.getEntity(column.getCategoryCategoryId());
+		}
+		model.addAttribute("columnSuper", columnSuper);
+		model.addAttribute("listColumn", JSONArray.toJSONString(list));
+		model.addAttribute("model", "cms");
+		return view("/column/form");
+	}
+	
+	/**
+	 * 栏目首页面列表显示
+	 */
+	@SuppressWarnings("deprecation")
+	@RequestMapping("/list")
+	public void list(@ModelAttribute ColumnEntity column,HttpServletResponse response, HttpServletRequest request,ModelMap model) {
+
+		// 站点ID有session获取
+		int websiteId = this.getAppId(request);
+		// 需要打开的栏目节点树的栏目ID
+		List list = columnBiz.queryAll(websiteId, this.getModelCodeId(request));
+		EUListBean _list = new EUListBean(list, list.size());
+		this.outJson(response, net.mingsoft.base.util.JSONArray.toJSONString(_list));
+	}
+	
+	/**
+	 * 栏目添加
+	 * 
+	 * @param column
+	 *            栏目对象
+	 * @return 返回页面跳转
+	 */
+	@RequestMapping("/save")
+	public void save(@ModelAttribute ColumnEntity column,HttpServletRequest request,HttpServletResponse response) {
+		if(!checkForm(column,response)){
+			return;
+		}
+		column.setCategoryAppId( this.getAppId(request));
+		column.setAppId(BasicUtil.getAppId());
+		column.setCategoryManagerId(getManagerBySession(request).getManagerId());
+		column.setCategoryDateTime(new Timestamp(System.currentTimeMillis()));
+		column.setCategoryModelId(this.getModelCodeId(request));
+		if(column.getColumnType()==ColumnEntity.ColumnTypeEnum.COLUMN_TYPE_COVER.toInt()){
+			column.setColumnListUrl(null);
+		}
+		columnBiz.saveCategory(column);
+		this.columnPath(request,column);
+		this.outJson(response, ModelCode.COLUMN, true,null,JSONArray.toJSONString(column.getCategoryId()));
+	}
+	
+	/**
+	 * 更新栏目
+	 * @param column 栏目实体
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/update")
+	@ResponseBody
+	public void update(@ModelAttribute ColumnEntity column,HttpServletRequest request,HttpServletResponse response) {
+		//获取站点ID
+		int websiteId = this.getAppId(request);
+		//检测栏目信息是否合法
+		if(!checkForm(column,response)){
+			return;
+		}
+		//若栏目管理属性为单页,则栏目的列表模板地址设为Null
+		if(column.getColumnType()==ColumnEntity.ColumnTypeEnum.COLUMN_TYPE_COVER.toInt()){
+			column.setColumnListUrl(null);
+		}
+		column.setCategoryManagerId(getManagerBySession(request).getManagerId());
+		column.setAppId(websiteId);
+		columnBiz.updateCategory(column);
+		this.columnPath(request,column);
+		//查询当前栏目是否有子栏目,
+		List<ColumnEntity> childList = columnBiz.queryChild(column.getCategoryId(), websiteId,this.getModelCodeId(request),null);
+		if(childList != null && childList.size()>0){
+			//改变子栏目的顶级栏目ID为当前栏目的父级栏目ID
+			for(int i=0;i<childList.size();i++){
+				childList.get(i).setCategoryCategoryId(column.getCategoryId());
+				childList.get(i).setCategoryManagerId(getManagerBySession(request).getManagerId());
+				childList.get(i).setAppId(websiteId);
+				columnBiz.updateCategory(childList.get(i));
+				//组织子栏目链接地址
+				this.columnPath(request, childList.get(i));
+			}
+		}
+		this.outJson(response, ModelCode.COLUMN, true,null,JSONArray.toJSONString(column.getCategoryId()));
+	}
+}

+ 252 - 0
src/main/java/net/mingsoft/cms/action/GeneraterAction.java

@@ -0,0 +1,252 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.action;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.alibaba.fastjson.JSONArray;
+import net.mingsoft.basic.action.BaseAction;
+import net.mingsoft.basic.biz.IColumnBiz;
+import net.mingsoft.basic.biz.IModelBiz;
+import net.mingsoft.basic.entity.AppEntity;
+import net.mingsoft.basic.entity.CategoryEntity;
+import net.mingsoft.basic.entity.ColumnEntity;
+import net.mingsoft.cms.bean.ColumnArticleIdBean;
+import net.mingsoft.cms.biz.IArticleBiz;
+import net.mingsoft.cms.constant.ModelCode;
+import net.mingsoft.cms.util.CmsParserUtil;
+import net.mingsoft.mdiy.biz.IContentModelBiz;
+import net.mingsoft.mdiy.biz.IContentModelFieldBiz;
+
+import cn.hutool.core.io.FileUtil;
+import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.mdiy.util.ParserUtil;
+
+/**
+ * 
+ * @ClassName: GeneraterAction
+ * @Description:TODO 生成器
+ * @author: 铭飞开发团队
+ * @date: 2018年1月31日 下午2:52:07
+ * 
+ * @Copyright: 2018 www.mingsoft.net Inc. All rights reserved.
+ */
+@Controller("cmsGenerater")
+@RequestMapping("/${ms.manager.path}/cms/generate")
+@Scope("request")
+public class GeneraterAction extends BaseAction {
+
+	/**
+	 * 文章管理业务层
+	 */
+	@Autowired
+	private IArticleBiz articleBiz;
+
+	/**
+	 * 栏目管理业务层
+	 */
+	@Autowired
+	private IColumnBiz columnBiz;
+
+	/**
+	 * 模块管理业务层
+	 */
+	@Autowired
+	private IModelBiz modelBiz;
+
+	@Value("${ms.manager.path}")
+	private String managerPath;
+
+	/**
+	 * 新增字段业务层
+	 */
+	@Autowired
+	protected IContentModelFieldBiz fieldBiz;
+
+	/**
+	 * 自定义模型业务层
+	 */
+	@Autowired
+	protected IContentModelBiz contentBiz;
+
+	/**
+	 * 更新主页
+	 * 
+	 * @return
+	 */
+	@RequestMapping("/index")
+	public String index(HttpServletRequest request, ModelMap model) {
+		// 该站点ID有session提供
+		int websiteId = BasicUtil.getAppId();
+		Integer modelId = modelBiz.getEntityByModelCode(ModelCode.CMS_COLUMN).getModelId(); // 查询当前模块编号
+		// 获取所有的内容管理栏目
+		List<ColumnEntity> list = columnBiz.queryAll(websiteId, modelId);
+		model.addAttribute("list", JSONArray.toJSONString(list));
+		model.addAttribute("now", new Date());
+		return view("/cms/generate/index");
+	}
+
+	/**
+	 * 生成主页
+	 * 
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/generateIndex")
+	@RequiresPermissions("cms:generate:index")
+	@ResponseBody
+	public void generateIndex(HttpServletRequest request, HttpServletResponse response) {
+		// 模版文件名称
+		String tmpFileName = request.getParameter("url");
+		// 生成后的文件名称
+		String generateFileName = request.getParameter("position");
+		
+		// 获取文件所在路径 首先判断用户输入的模版文件是否存在
+		if (!FileUtil.exist(ParserUtil.buildTempletPath())) {
+			this.outJson(response, false, getResString("templet.file"));
+		} else {
+			try {
+				CmsParserUtil.generate(tmpFileName, generateFileName);
+				this.outJson(response, true);
+			} catch (IOException e) {
+				e.printStackTrace();
+				this.outJson(response, false);
+			}
+		}
+	}
+	
+
+
+	/**
+	 * 生成列表的静态页面
+	 * 
+	 * @param request
+	 * @param response
+	 * @param columnId
+	 */
+	@RequestMapping("/{columnId}/genernateColumn")
+	@RequiresPermissions("cms:generate:column")
+	@ResponseBody
+	public void genernateColumn(HttpServletRequest request, HttpServletResponse response, @PathVariable int columnId) {
+		// 获取站点id
+		AppEntity app = BasicUtil.getApp();
+		List<ColumnEntity> columns = new ArrayList<ColumnEntity>();
+		// 如果栏目id小于0则更新所有的栏目,否则只更新选中的栏目
+		int modelId = BasicUtil.getModelCodeId(ModelCode.CMS_COLUMN); // 查询当前模块编号
+		if (columnId > 0) {
+			List<CategoryEntity> categorys = columnBiz.queryChildrenCategory(columnId, app.getAppId(), modelId);
+			for (CategoryEntity c : categorys) {
+				columns.add((ColumnEntity) columnBiz.getEntity(c.getCategoryId()));
+			}
+		} else {
+			// 获取所有的内容管理栏目
+			columns = columnBiz.queryAll(app.getAppId(), modelId);
+		}
+		List<ColumnArticleIdBean> articleIdList = null;
+		try {
+			// 1、设置模板文件夹路径
+			// 获取栏目列表模版
+			for (ColumnEntity column : columns) {
+				// 判断模板文件是否存在
+				if (!FileUtil.exist(ParserUtil.buildTempletPath(column.getColumnUrl()))) {
+					continue;
+				}
+				articleIdList = articleBiz.queryIdsByCategoryIdForParser(column.getCategoryId(), null, null);
+				// 判断列表类型
+				switch (column.getColumnType()) {
+				case ColumnEntity.COLUMN_TYPE_LIST: // 列表
+					CmsParserUtil.generateList(column, articleIdList.size());
+					break;
+				case ColumnEntity.COLUMN_TYPE_COVER:// 单页
+					CmsParserUtil.generateBasic(articleIdList);
+					break;
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+			this.outJson(response, false);
+		}
+		this.outJson(response, true);
+	}
+
+	/**
+	 * 根据栏目id更新所有的文章
+	 * 
+	 * @param request
+	 * @param response
+	 * @param columnId
+	 */
+	@RequestMapping("/{columnId}/generateArticle")
+	@RequiresPermissions("cms:generate:article")
+	@ResponseBody
+	public void generateArticle(HttpServletRequest request, HttpServletResponse response, @PathVariable int columnId) {
+		String dateTime = request.getParameter("dateTime");
+		// 网站风格物理路径
+		List<ColumnArticleIdBean> articleIdList = null;
+		try {
+			// 查出所有文章(根据选择栏目)包括子栏目
+			articleIdList = articleBiz.queryIdsByCategoryIdForParser(columnId, dateTime, null);
+			// 有符合条件的新闻就更新
+			if (articleIdList.size() > 0) {
+				CmsParserUtil.generateBasic(articleIdList);
+			}
+			this.outJson(response, true);
+		} catch (IOException e) {
+			e.printStackTrace();
+			this.outJson(response, false);
+		}
+	}
+	
+
+
+	/**
+	 * 用户预览主页
+	 * 
+	 * @param request
+	 * @return
+	 */
+	@RequestMapping("/{position}/viewIndex")
+	public String viewIndex(HttpServletRequest request, @PathVariable String position, HttpServletResponse response) {
+		AppEntity app = BasicUtil.getApp();
+		// 组织主页预览地址
+		String indexPosition = app.getAppHostUrl() + File.separator + ParserUtil.HTML + File.separator + app.getAppId()
+				+ File.separator + position + ParserUtil.HTML_SUFFIX;
+		return "redirect:" + indexPosition;
+	}
+}

+ 231 - 0
src/main/java/net/mingsoft/cms/action/web/ArticleAction.java

@@ -0,0 +1,231 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.action.web;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import net.mingsoft.basic.action.BaseAction;
+import net.mingsoft.basic.biz.IColumnBiz;
+import net.mingsoft.basic.entity.ColumnEntity;
+import net.mingsoft.cms.biz.IArticleBiz;
+import net.mingsoft.cms.entity.ArticleEntity;
+import net.mingsoft.mdiy.biz.IContentModelBiz;
+import net.mingsoft.mdiy.biz.IContentModelFieldBiz;
+import net.mingsoft.mdiy.entity.ContentModelEntity;
+import org.apache.commons.lang3.StringUtils;
+
+import cn.hutool.core.util.ObjectUtil;
+import net.mingsoft.base.filter.DateValueFilter;
+import net.mingsoft.basic.bean.ListBean;
+import net.mingsoft.basic.util.BasicUtil;
+
+/**
+ * 
+ * @ClassName:  ArticleAction   
+ * @Description:TODO 前段文章控制,如果标签不能满足可以使用这个控制来满足用户的查询文章需求,主要是通过ajax返回json数据格式   
+ * @author: 铭飞开发团队
+ * @date:   2018年1月31日 下午2:52:44   
+ *     
+ * @Copyright: 2018 www.mingsoft.net Inc. All rights reserved.
+ */
+@Controller("jsonApiArticle")
+@RequestMapping("/mcms/article")
+public class ArticleAction extends BaseAction {
+
+	/**
+	 * 文章管理业务处理层
+	 */
+	@Autowired
+	private IArticleBiz articleBiz;
+
+	/**
+	 * 栏目管理业务处理层
+	 */
+	@Autowired
+	private IColumnBiz columnBiz;
+
+	/**
+	 * 内容模型管理业务处理层
+	 */
+	@Autowired
+	private IContentModelBiz contentModelBiz;
+
+	/**
+	 * 自定义字段管理业务处理层
+	 */
+	@Autowired
+	private IContentModelFieldBiz fieldBiz;
+
+	/**
+	 * 文章信息
+	 * 
+	 * @param basicId
+	 *            文章编号
+	 *            <dt><span class="strong">返回</span></dt><br/>
+	 *            {"basicCategoryId":分类编号,basicTitle
+	 *            :"标题",basicDescription:"描述",basicThumbnails:"缩略图",
+	 *            basicDateTime:"发布时间",basicUpdateTime:"更新时间","basicHit":点击数,
+	 *            "basicId":编号 articleContent:"文章内容","basicSort":排序,[自定义模型字段]}
+	 */
+	@RequestMapping("/{basicId}/detail")
+	@ResponseBody
+	public void detail(@PathVariable int basicId, HttpServletRequest request, HttpServletResponse response) {
+		System.out.println(BasicUtil.getSession("xxx"));
+		//ArticleEntity article = articleBiz.getById(basicId);
+//		if (article == null) {
+//			this.outJson(response, "");
+//			return;
+//		}
+//		// 获取文章栏目id获取栏目实体
+//		ColumnEntity column = (ColumnEntity) columnBiz.getEntity(article.getBasicCategoryId());
+//		ContentModelEntity contentModel = (ContentModelEntity) contentModelBiz
+//				.getEntity(column.getColumnContentModelId());
+//
+//		// 判断内容模型的值
+//		if (contentModel != null) {
+//			Map where = new HashMap();
+//			// 压入basicId字段的值
+//			where.put("basicId", basicId);
+//			// 遍历所有的字段实体,得到字段名列表信息
+//			List<String> listFieldName = new ArrayList<String>();
+//			listFieldName.add("basicId");
+//			// 查询新增字段的信息
+//			List fieldLists = fieldBiz.queryBySQL(contentModel.getCmTableName(), listFieldName, where);
+//			if (fieldLists.size() > 0) {
+//				Map map = (Map) fieldLists.get(0);
+//				article.setExtendsFields(map);
+//			}
+//		}
+//
+//		this.outJson(response, JSONObject.toJSONStringWithDateFormat(article, "yyyy-MM-dd hh:mm:ss"));
+	}
+
+
+	/**
+	 * 文章列表信息
+	 * 
+	 * @param pageSize
+	 *            一页显示数量
+	 * @param pageNum
+	 *            当前页码
+	 * @param basicCategoryId
+	 *            分类编号
+	 *            <dt><span class="strong">返回</span></dt><br/>
+	 *            {"list":"[{
+	 *            "basicTitle":"标题",
+	 *            "basicDescription":"描述",
+	 *            "basicThumbnails":"缩略图",
+	 *            "basicDateTime":"发布时间",
+	 *            "basicUpdateTime":"更新时间",
+	 *            "basicHit":点击数,
+	 *            "basicId":编号,
+	 *            "articleContent":文章内容,
+	 *            "articleAuthor":文章作者
+	 *      	  "articleType":文章属性,
+	 *      	  "articleSource":文章的来源,
+	 *      	  "articleUrl":文章跳转链接地址,
+	 *      	  "articleKeyword":文章关键字,
+	 *      	  "articleCategoryId":文章所属的分类Id,
+	 *      	  "articleTypeLinkURL":文章分类url地址,主要是用户生成html使用,
+	 *            "order":"排序方式",
+	 *            "orderBy":"排序字段     
+	 *            }],
+	 *             "page":{"endRow": 2,  当前页面最后一个元素在数据库中的行号
+	 * 				"firstPage": 1, 第一页页码
+	 * 				"hasNextPage": true存在下一页false不存在, 
+	 * 				"hasPreviousPage": true存在上一页false不存在, 
+	 * 				"isFirstPage": true是第一页false不是第一页, 
+	 * 				"isLastPage": true是最后一页false不是最后一页, 
+	 * 				"lastPage": 最后一页的页码, 
+	 * 				"navigatePages": 导航数量,实现 1...5.6.7....10效果, 
+	 * 				"navigatepageNums": []导航页码集合, 
+	 * 				"nextPage": 下一页, 
+	 * 				"pageNum": 当前页码, 
+	 * 				"pageSize": 一页显示数量, 
+	 * 				"pages": 总页数, 
+	 * 				"prePage": 上一页, 
+	 * 				"size": 总记录, 
+	 * 				"startRow":当前页面第一个元素在数据库中的行号, 
+	 * 				"total":总记录数量
+	 * 				}
+	 */
+	@RequestMapping(value = "/list")
+	@ResponseBody
+	public void list(@ModelAttribute ArticleEntity article, HttpServletRequest request, HttpServletResponse response) {
+		int appId = BasicUtil.getAppId();
+		int[] ids = null;
+		if (article.getBasicCategoryId()>0) {
+			 ids = new int[]{article.getBasicCategoryId()};
+		}
+		//默认为desc排序
+		boolean isOrder = true;
+		if(!StringUtils.isBlank(article.getOrder())){
+			String	basicOrder = article.getOrder();
+			if(basicOrder.equalsIgnoreCase("asc")){
+				isOrder = false;
+			}
+		}
+		BasicUtil.startPage();
+		List<ArticleEntity> list = articleBiz.query(appId, ids, null, null, article.getOrderBy(), isOrder, null, null, article);
+		
+		for(ArticleEntity _article : list){
+			// 获取文章栏目id获取栏目实体
+			ColumnEntity column = (ColumnEntity) columnBiz.getEntity(_article.getBasicCategoryId());
+			ContentModelEntity contentModel = (ContentModelEntity) contentModelBiz
+					.getEntity(column.getColumnContentModelId());
+
+			// 判断内容模型的值
+			if (contentModel != null) {
+				Map where = new HashMap();
+				// 压入basicId字段的值
+				where.put("basicId", _article.getBasicId());
+				// 遍历所有的字段实体,得到字段名列表信息
+				List<String> listFieldName = new ArrayList<String>();
+				listFieldName.add("basicId");
+				// 查询新增字段的信息
+				List fieldLists = fieldBiz.queryBySQL(contentModel.getCmTableName(), listFieldName, where);
+				if (fieldLists.size() > 0) {
+					Map map = (Map) fieldLists.get(0);
+					_article.setExtendsFields(map);
+				}
+			}
+		}
+		
+		this.outJson(response, JSONArray.toJSONString(new ListBean(list, BasicUtil.endPage(list)),new DateValueFilter("yyyy-MM-dd HH:mm:ss")));
+	}
+
+}

+ 128 - 0
src/main/java/net/mingsoft/cms/action/web/FieldAction.java

@@ -0,0 +1,128 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.action.web;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.alibaba.fastjson.JSONObject;
+import net.mingsoft.basic.biz.IColumnBiz;
+import net.mingsoft.mdiy.biz.IContentModelBiz;
+import net.mingsoft.mdiy.biz.IContentModelFieldBiz;
+import net.mingsoft.basic.entity.ColumnEntity;
+import net.mingsoft.mdiy.entity.ContentModelEntity;
+import net.mingsoft.mdiy.entity.ContentModelFieldEntity;
+
+import net.mingsoft.base.action.BaseAction;
+import net.mingsoft.basic.util.BasicUtil;
+
+/**
+ * 
+ * 
+ * 
+ * <p>
+ * <b>铭飞科技</b>
+ * </p>
+ * 
+ * <p>
+ * Copyright: Copyright (c) 2014 - 2015
+ * </p>
+ *
+ * @author 史爱华
+ *
+ * <p>
+ * Comments: 供前端页面获取自定义模型中字段实体信息
+ * </p>
+ *
+ * <p>
+ * Create Date:2015-07-11
+ * </p>
+ *
+ * <p>
+ * Modification history:
+ * </p>
+ */
+@Controller("webField")
+@RequestMapping("/field")
+public class FieldAction extends BaseAction{
+	
+	/**
+	 * 栏目业务层
+	 */
+	@Autowired
+	private IColumnBiz columnBiz;
+	
+	/**
+	 * 内容模型业务层
+	 */
+	@Autowired
+	private IContentModelBiz contentModelBiz;
+	
+	/**
+	 * 字段管理业务层
+	 */
+	@Autowired
+	private IContentModelFieldBiz fieldBiz;
+	
+	/**
+	 * 
+	 * 根据当前栏目id和字段名称获取自定义模型中的字段实体信息
+	 * @param request
+	 * @param response
+	 */
+	@RequestMapping("/{columId}/getEntity")
+	@ResponseBody
+	public void getEntity(@PathVariable int columId,HttpServletRequest request, HttpServletResponse response) {
+		System.out.println("111");
+		BasicUtil.setSession("xxx", "888");
+		System.err.println("session:"+BasicUtil.getSession("xxx"));
+		//获取字段名称
+		String fieldFieldName = request.getParameter("fieldFieldName");
+		//根据栏目id获取栏目实体
+		ColumnEntity column = (ColumnEntity) this.columnBiz.getEntity(columId);
+		if(column==null){
+			this.outJson(response, this.getResString("err"));
+			return;
+		}else{
+			//判断该栏目下是存在内容模型
+			if(column.getColumnContentModelId()>0){
+				//获取当前栏目对应的内容模型
+				ContentModelEntity contentModel = (ContentModelEntity) this.contentModelBiz.getEntity(column.getColumnContentModelId());
+				if(contentModel==null){
+					this.outJson(response, this.getResString("err"));
+					return;
+				}
+				//获取字段实体
+				ContentModelFieldEntity field = fieldBiz.getEntityByCmId(column.getColumnContentModelId(), fieldFieldName);
+				//返回字段实体
+				this.outJson(response, JSONObject.toJSONString(field));
+			}
+		}
+		
+	}
+}

+ 227 - 0
src/main/java/net/mingsoft/cms/action/web/MCmsAction.java

@@ -0,0 +1,227 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.action.web;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import net.mingsoft.basic.biz.IColumnBiz;
+import net.mingsoft.basic.entity.ColumnEntity;
+import net.mingsoft.cms.bean.ColumnArticleIdBean;
+import net.mingsoft.cms.biz.IArticleBiz;
+import net.mingsoft.cms.entity.ArticleEntity;
+import net.mingsoft.cms.util.CmsParserUtil;
+import net.mingsoft.mdiy.biz.IPageBiz;
+import net.mingsoft.mdiy.entity.PageEntity;
+
+import freemarker.core.ParseException;
+import freemarker.template.MalformedTemplateNameException;
+import freemarker.template.TemplateNotFoundException;
+import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.mdiy.util.ParserUtil;
+
+/**
+ * 动态生成页面,需要后台配置自定义页数据
+ * 
+ * @author 铭飞开源团队
+ * @date 2018年12月17日
+ */
+@Controller("dynamicPageAction")
+@RequestMapping("/mcms")
+public class MCmsAction extends net.mingsoft.mdiy.action.BaseAction {
+
+	/**
+	 * 自定义页面业务层
+	 */
+	@Autowired
+	private IPageBiz pageBiz;
+
+	/**
+	 * 文章管理业务处理层
+	 */
+	@Autowired
+	private IArticleBiz articleBiz;
+
+	/**
+	 * 栏目业务层
+	 */
+	@Autowired
+	private IColumnBiz columnBiz;
+
+
+	// 如商城就为:/mall/{key}.do
+	/**
+	 * 前段会员中心所有页面都可以使用该方法 请求地址例如: /{diy}.do,例如登陆界面,与注册界面都可以使用
+	 * 
+	 * @param key
+	 */
+	@RequestMapping("/{diy}.do")
+	@ExceptionHandler(java.lang.NullPointerException.class)
+	public void diy(@PathVariable(value = "diy") String diy, HttpServletRequest req, HttpServletResponse resp) {
+		Map map = BasicUtil.assemblyRequestMap();
+		//动态解析
+		map.put(ParserUtil.IS_DO,true);
+		//设置动态请求的模块路径
+		map.put(ParserUtil.MODEL_NAME, "mcms");
+		//解析后的内容
+		String content = "";
+		PageEntity page = new PageEntity();
+		page.setPageKey(diy);
+		//根据请求路径查询模版文件
+		PageEntity _page = (PageEntity) pageBiz.getEntity(page);
+		try {
+			content = CmsParserUtil.generate(_page.getPagePath(), map, isMobileDevice(req));
+		} catch (TemplateNotFoundException e) {
+			e.printStackTrace();
+		} catch (MalformedTemplateNameException e) {
+			e.printStackTrace();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		this.outString(resp, content);
+	}
+
+	/**
+	 * 动态列表页
+	 */
+	@GetMapping("/index.do")
+	public void index(HttpServletRequest req, HttpServletResponse resp) {
+		Map map = BasicUtil.assemblyRequestMap();
+		map.put(ParserUtil.URL, BasicUtil.getUrl());
+		//动态解析
+		map.put(ParserUtil.IS_DO,true);
+		//设置动态请求的模块路径
+		map.put(ParserUtil.MODEL_NAME, "mcms");
+		//解析后的内容
+		String content = "";
+		try {
+			//根据模板路径,参数生成
+			content = CmsParserUtil.generate(ParserUtil.INDEX+ParserUtil.HTM_SUFFIX, map, isMobileDevice(req));
+		} catch (TemplateNotFoundException e) {
+			e.printStackTrace();
+		} catch (MalformedTemplateNameException e) {
+			e.printStackTrace();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		this.outString(resp, content);
+	}
+
+	/**
+	 * 动态列表页
+	 * @param req
+	 * @param resp
+	 * @param pageNumber 设置列表当前页
+	 * @param typeid 栏目编号
+	 * @param size 显示条数
+	 */
+	@GetMapping("/list.do")
+	public void list(HttpServletRequest req, HttpServletResponse resp) {
+		Map map = BasicUtil.assemblyRequestMap();
+		//获取栏目编号
+		int typeId = BasicUtil.getInt(ParserUtil.TYPE_ID,0);
+		//获取文章总数
+		List<ColumnArticleIdBean> columnArticles = articleBiz.queryIdsByCategoryIdForParser(typeId, null, null);
+		//判断栏目下是否有文章
+		if(columnArticles.size()==0){
+			this.outJson(resp, false);
+		}
+		map.put(ParserUtil.COLUMN, columnArticles.get(0));
+		//获取总数
+		map.put(ParserUtil.TOTAL, columnArticles.size());
+		map.put(ParserUtil.RCOUNT, BasicUtil.getInt(ParserUtil.SIZE,10));
+		//设置栏目编号
+		map.put(ParserUtil.TYPE_ID, typeId);
+		//设置列表当前页
+		map.put(ParserUtil.PAGE_NO, BasicUtil.getInt(ParserUtil.PAGE_NO,1));
+		
+		map.put(ParserUtil.URL, BasicUtil.getUrl());
+		
+		//动态解析
+		map.put(ParserUtil.IS_DO,true);
+		//设置动态请求的模块路径
+		map.put(ParserUtil.MODEL_NAME, "mcms");
+		//解析后的内容
+		String content = "";
+		try {
+			//根据模板路径,参数生成
+			content = CmsParserUtil.generate(columnArticles.get(0).getColumnListUrl(),map, isMobileDevice(req));
+		} catch (TemplateNotFoundException e) {
+			e.printStackTrace();
+		} catch (MalformedTemplateNameException e) {
+			e.printStackTrace();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		this.outString(resp, content);
+	}
+	
+	/**
+	 * 动态详情页
+	 * @param id 文章编号
+	 */
+	@GetMapping("/view.do")
+	public void view(HttpServletRequest req, HttpServletResponse resp) {
+		//参数文章编号
+		ArticleEntity article = (ArticleEntity) articleBiz.getEntity(BasicUtil.getInt(ParserUtil.ID));
+		//根据文章编号查询栏目详情模版
+		ColumnEntity column = (ColumnEntity) columnBiz.getEntity(article.getBasicCategoryId());
+		//解析后的内容
+		String content = "";
+		Map map = BasicUtil.assemblyRequestMap();
+		//动态解析
+		map.put(ParserUtil.IS_DO,true);
+		//设置动态请求的模块路径
+		map.put(ParserUtil.MODEL_NAME, "mcms");
+		map.put(ParserUtil.URL, BasicUtil.getUrl());
+		try {
+			//根据模板路径,参数生成
+			content = CmsParserUtil.generate(column.getColumnUrl(), map, isMobileDevice(req));
+		} catch (TemplateNotFoundException e) {
+			e.printStackTrace();
+		} catch (MalformedTemplateNameException e) {
+			e.printStackTrace();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		this.outString(resp, content);
+	}
+}

+ 290 - 0
src/main/java/net/mingsoft/cms/action/web/SearchAction.java

@@ -0,0 +1,290 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.action.web;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+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.ResponseBody;
+
+import net.mingsoft.basic.action.BaseAction;
+import net.mingsoft.basic.biz.IColumnBiz;
+import net.mingsoft.basic.entity.ColumnEntity;
+import net.mingsoft.cms.biz.IArticleBiz;
+import net.mingsoft.cms.util.CmsParserUtil;
+import net.mingsoft.mdiy.biz.ISearchBiz;
+import net.mingsoft.mdiy.entity.ContentModelFieldEntity;
+import net.mingsoft.mdiy.entity.SearchEntity;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.PageUtil;
+import freemarker.core.ParseException;
+import freemarker.template.MalformedTemplateNameException;
+import freemarker.template.TemplateNotFoundException;
+import net.mingsoft.base.constant.Const;
+import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.mdiy.util.ParserUtil;
+
+/**
+ * 根据搜索结果动态解析模版内容
+ * @author 铭飞开源团队-Administrator  
+ * @date 2018年12月18日
+ */
+@Controller(value = "webSearchAction")
+@RequestMapping("/cms")
+public class SearchAction extends BaseAction {
+
+	/**
+	 * 搜索标签;
+	 */
+	public static final String SEARCH = "search";
+	
+	/**
+	 * 搜索的标题;
+	 */
+	public static final String BASIC_TITLE = "basic_title";
+	
+	/**
+	 * 注入文章业务层
+	 */
+	@Autowired
+	private IArticleBiz articleBiz;
+
+	/**
+	 * 注入搜索业务层
+	 */
+	@Autowired
+	private ISearchBiz searchBiz;
+
+	/**
+	 * 注入栏目业务层
+	 */
+	@Autowired
+	private IColumnBiz columnBiz;
+	/**
+	 * 实现前端页面的文章搜索
+	 * 
+	 * @param request
+	 * @param searchId
+	 *            搜索id
+	 * @param response
+	 */
+	@RequestMapping(value = "/{searchId}/search")
+	@ResponseBody
+	public void search(HttpServletRequest request, @PathVariable int searchId, HttpServletResponse response) {
+		SearchEntity _search = new SearchEntity();
+		_search.setAppId(BasicUtil.getAppId());
+		_search.setSearchId(searchId);
+		// 获取对应搜索模型
+		SearchEntity search = (SearchEntity) searchBiz.getEntity(_search); 
+		//判断当前搜索是否有模板文件
+		if (ObjectUtil.isNull(search)) {
+			this.outJson(response, false);
+		}
+		Map map = BasicUtil.assemblyRequestMap();
+		// 读取请求字段
+		Map<String, String[]> field =  request.getParameterMap(); 
+		Map<String, String> basicField = getMapByProperties(net.mingsoft.mdiy.constant.Const.BASIC_FIELD);
+		// 文章字段集合
+		Map<String, Object> articleFieldName = new HashMap<String, Object>();
+		// 遍历取字段集合
+		if (field != null) {
+			for (Entry<String, String[]> entry : field.entrySet()) {
+				if (entry != null) {
+					String value = entry.getValue()[0]; // 处理由get方法请求中文乱码问题
+					if (ObjectUtil.isNull(value)) {
+						continue;
+					}
+					if (request.getMethod().equals(RequestMethod.GET)) { // 如果是get方法需要将请求地址参数转吗
+						try {
+							value = new String(value.getBytes("ISO-8859-1"),Const.UTF8);
+						} catch (UnsupportedEncodingException e) {
+							e.printStackTrace();
+						}
+					}
+					// 若为文章字段,则保存至文章字段集合;否则保存至自定义字段集合
+					if (ObjectUtil.isNotNull(basicField.get(entry.getKey())) && ObjectUtil.isNotNull(value)) {
+						articleFieldName.put(entry.getKey(), value);
+					} 
+				}
+			}
+		}
+		Map whereMap = this.searchMap(articleFieldName, null, null);
+		// 获取符合条件的文章总数
+		int count = articleBiz.getSearchCount(null, whereMap, BasicUtil.getAppId(), null);
+		int typeId = BasicUtil.getInt("categoryId",0);
+		//根据栏目确定模版
+		if(typeId>0){
+			ColumnEntity column = (ColumnEntity) columnBiz.getEntity(Integer.parseInt(map.get("typeid")+""));
+			map.put(ParserUtil.COLUMN, column);
+			//设置栏目编号
+			map.put(ParserUtil.TYPE_ID, typeId);
+		}
+		int size = BasicUtil.getInt(ParserUtil.SIZE,10);
+		//获取总数
+		map.put(ParserUtil.TOTAL, PageUtil.totalPage(count, size));
+		//设置页面显示数量
+		map.put(ParserUtil.RCOUNT, size);
+		//设置列表当前页
+		map.put(ParserUtil.PAGE_NO, BasicUtil.getInt(ParserUtil.PAGE_NO,1));
+		
+		map.put(ParserUtil.URL, BasicUtil.getUrl());
+		Map searchMap = new HashMap<>();
+		searchMap.put(BASIC_TITLE, BasicUtil.getString(BASIC_TITLE));
+		map.put(SEARCH, searchMap);
+		//动态解析
+		map.put(ParserUtil.IS_DO,true);
+		//设置动态请求的模块路径
+		map.put(ParserUtil.MODEL_NAME, "mcms");
+		//解析后的内容
+		String content = "";
+		try {
+			//根据模板路径,参数生成
+			content = CmsParserUtil.generate(search.getSearchTemplets(),map, isMobileDevice(request));
+		} catch (TemplateNotFoundException e) {
+			e.printStackTrace();
+		} catch (MalformedTemplateNameException e) {
+			e.printStackTrace();
+		} catch (ParseException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		this.outString(response, content);
+	}
+
+	/**
+	 * 动态组织查询where条件 获取查询条件的Map key:字段名 value:List 字段的各种判断值 list[0]:是否为自定义字段
+	 * list[1]:是否为整形 list[2]:是否是等值查询 list[3]:字段的值
+	 * 
+	 * @param articleField
+	 *            文章字段
+	 * @param diyFieldName
+	 *            动态字段
+	 * @param fields
+	 *            模型对应的字段类型
+	 * @return
+	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private Map<String, List> searchMap(Map<String, Object> articleField, Map<String, String> diyFieldName,
+			List fields) {
+		Map<String, List> map = new HashMap<String, List>();
+
+		// 遍历文章中的字段
+		for (Iterator iter = articleField.keySet().iterator(); iter.hasNext();) {
+			String key = iter.next().toString();
+			String fieldValue = articleField.get(key).toString();
+			List list = new ArrayList();
+			List listValue = new ArrayList();
+			// 是否为自定义字段
+			list.add(false);
+
+			// 是否是数字类型,true:不是
+			list.add(true);
+			// 是否是模糊查询3
+			list.add(true);
+			// 字段值
+			listValue.add(articleField.get(key));
+			list.add(listValue);
+			map.put(key, list);
+		}
+
+		// 遍历字段自定义字段
+//		for (Iterator iter = diyFieldName.keySet().iterator(); iter.hasNext();) {
+//			String key = iter.next().toString();
+//			String fieldValue = diyFieldName.get(key);
+//			// 获取字段实体
+//			ContentModelFieldEntity field = this.get(key, fields);
+//			if (field != null) {
+//				List list = new ArrayList();
+//				// 是否为自定义字段0
+//				list.add(0, true);
+//				List listValue = new ArrayList();
+//				// 字段的值
+//				if (field.getFieldType() == IContentModelFieldBiz.INT || field.getFieldType() == IContentModelFieldBiz.FLOAT) {
+//					// 判断是否为区间查询
+//
+//					if (diyFieldName.get(key).toString().indexOf("-") > 0) {
+//						String[] values = fieldValue.toString().split("-");
+//						// 是否是数字类型,false:是
+//						list.add(false);
+//						// 是否是区间比较 false:是
+//						list.add(false);
+//						// 字段值1
+//						listValue.add(values[0]);
+//						listValue.add(values[1]);
+//					} else {
+//						// 是否是数字类型,false:是2
+//						list.add(false);
+//						// 是否是区间比较 true:不是3
+//						list.add(true);
+//						// 字段值 1
+//						listValue.add(fieldValue);
+//					}
+//				} else {
+//					// 是否是数字类型,true:不是2
+//					list.add(true);
+//					list.add(false);
+//					// 字段值 1
+//					listValue.add(fieldValue);
+//				}
+//				list.add(listValue);
+//				map.put(key, list);
+//			}
+//		}
+		return map;
+	}
+
+	/**
+	 * 根据字段名称获取字段类型
+	 * 
+	 * @param columnName
+	 *            字段名称
+	 * @return 字段实体
+	 */
+	private ContentModelFieldEntity get(String columnName, List<ContentModelFieldEntity> fields) {
+		if (fields == null) {
+			return null;
+		}
+		for (ContentModelFieldEntity field : fields) {
+			if (field.getFieldFieldName().equals(columnName)) {
+				return field;
+			}
+		}
+		return null;
+	}
+
+}

+ 45 - 0
src/main/java/net/mingsoft/cms/bean/ColumnArticleIdBean.java

@@ -0,0 +1,45 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.bean;
+
+import net.mingsoft.basic.entity.ColumnEntity;
+
+/**
+ * 文章解析生成
+ * @author 铭飞开源团队  
+ * @date 2018年12月13日
+ */
+public class ColumnArticleIdBean extends ColumnEntity{
+	/**
+	 * 文章编号
+	 */
+	private int articleId;
+
+	public int getArticleId() {
+		return articleId;
+	}
+
+	public void setArticleId(int articleId) {
+		this.articleId = articleId;
+	}
+	
+}

+ 183 - 0
src/main/java/net/mingsoft/cms/biz/IArticleBiz.java

@@ -0,0 +1,183 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.biz;
+
+import java.util.List;
+import java.util.Map;
+
+import net.mingsoft.basic.biz.IBasicBiz;
+import net.mingsoft.cms.bean.ColumnArticleIdBean;
+import net.mingsoft.cms.entity.ArticleEntity;
+import net.mingsoft.mdiy.entity.ContentModelEntity;
+
+
+/**
+ * 
+ * @ClassName:  IArticleBiz   
+ * @Description:TODO(文章管理业务处理层 || 继承IBasicBiz业务处理层)   
+ * @author: 铭飞开发团队
+ * @date:   2018年1月31日 下午2:53:32   
+ *     
+ * @Copyright: 2018 www.mingsoft.net Inc. All rights reserved.
+ */
+public interface IArticleBiz extends IBasicBiz {
+
+	/**
+	 * @para webId 网站编号
+	 * @param basicCategoryId
+	 *            栏目编号
+	 * @param flag
+	 *            文章属性
+	 * @param noFlag
+	 *            文章不存在的属性
+	 * @param article
+	 *            文件实体
+	 * @return
+	 */
+	@Deprecated
+	int count(int webId, int[] basicCategoryId, String flag, String noFlag, ArticleEntity article);
+
+
+	/**
+	 * 通过分类id获取文章内容
+	 * 
+	 * @param categoryId
+	 *            分类编号
+	 * @return
+	 */
+	@Deprecated
+	public ArticleEntity getByCategoryId(int categoryId);
+
+	/**
+	 * 通过视图表来查询文章总数
+	 * 
+	 * @param basicId
+	 *            文章编号
+	 */
+	public ArticleEntity getById(int basicId);
+
+
+	/**
+	 * 查找basicId下一篇文章
+	 * 
+	 * @param appId
+	 *            应用编号
+	 * @param basicId
+	 *            文章编号
+	 * @return
+	 */
+	@Deprecated
+	public ArticleEntity getNext(int appId, int basicId, Integer categoryId);
+
+	/**
+	 * 查找basicId上一篇文章
+	 * 
+	 * @param appId
+	 *            应用编号
+	 * @param basicId
+	 *            文章编号
+	 * @return
+	 */
+	@Deprecated
+	public ArticleEntity getPrevious(int appId, int basicId, Integer categoryId);
+
+	/**
+	 * 高级查询接口,主要提供给有自定义模型的栏目,返回總數
+	 * 
+	 * @param contentModel
+	 *            自定义模型
+	 * @param whereMap
+	 *            條件
+	 * @param appId
+	 *            appId 應用編號
+	 * @param ids
+	 *            子类id
+	 * @return 记录数量
+	 * @see IArticleBiz.count
+	 */
+	@Deprecated
+	public int getSearchCount(ContentModelEntity contentModel, Map whereMap, int appId, List ids);
+
+	/**
+	 * 文章查询
+	 * 
+	 * @para webId 网站编号
+	 * @param basicCategoryIds
+	 *            栏目编号集合
+	 * @param flag
+	 *            文章属性
+	 * @param noFlag
+	 *            文章不存在的属性
+	 * @param orderBy
+	 *            排序字段
+	 * @param order
+	 *            true 升序 false 降序 排序方式
+	 * @param beginTime 开始时间    
+	 * @param endTime 结束时间                
+	 * @param article
+	 *            文章实体,便于扩展查询
+	 * @return 文章集合
+	 */
+	List<ArticleEntity> query(int webId, int[] basicCategoryIds, String flag, String noFlag, String orderBy,
+			boolean order, String beginTime,String endTime, ArticleEntity article);
+
+	/**
+	 * 查询文章编号集合
+	 * @param categoryId 栏目编号
+	 * @param beginTime 开始时间
+	 * @param endTime 结束时间
+	 * @return
+	 */
+	public List<ColumnArticleIdBean> queryIdsByCategoryIdForParser(int categoryId, String beginTime,String endTime);
+
+	/**
+	 * 根据页面栏目的id获取与其绑定的文章实体
+	 * 
+	 * @param basicCategoryId
+	 * @return 文章实体
+	 */
+	@Deprecated
+	public List<ArticleEntity> queryListByColumnId(int basicCategoryId);
+
+
+
+
+	/**
+	 * 高级查询接口,主要提供给有自定义模型的栏目,
+	 * 
+	 * @param conntentModel
+	 *            自定义模型
+	 * @param whereMap
+	 *            條件
+	 * @param page
+	 *            分頁
+	 * @param appId
+	 *            應用編號
+	 * @param ids
+	 *            子类id
+	 * @return 记录集合
+	 */
+	@Deprecated
+	public List<ArticleEntity> queryListForSearch(ContentModelEntity conntentModel, Map whereMap,
+			int appId, List ids, Map orders);
+
+}

+ 219 - 0
src/main/java/net/mingsoft/cms/biz/impl/ArticleBizImpl.java

@@ -0,0 +1,219 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.biz.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import net.mingsoft.basic.biz.ICategoryBiz;
+import net.mingsoft.basic.biz.IColumnBiz;
+import net.mingsoft.basic.biz.IModelBiz;
+import net.mingsoft.basic.biz.impl.BasicBizImpl;
+import net.mingsoft.cms.bean.ColumnArticleIdBean;
+import net.mingsoft.cms.biz.IArticleBiz;
+import net.mingsoft.cms.dao.IArticleDao;
+import net.mingsoft.cms.entity.ArticleEntity;
+import net.mingsoft.mdiy.biz.IContentModelBiz;
+import net.mingsoft.mdiy.entity.ContentModelEntity;
+
+import net.mingsoft.base.dao.IBaseDao;
+import net.mingsoft.basic.util.BasicUtil;
+
+/**
+ * 
+ * @ClassName:  ArticleBizImpl   
+ * @Description:TODO(文章管理业务层实现类 || 继承BasicBizImpl || 实现IArticleBiz)   
+ * @author: 铭飞开发团队
+ * @date:   2018年1月31日 下午2:53:53   
+ *     
+ * @Copyright: 2018 www.mingsoft.net Inc. All rights reserved.
+ */
+@Service("ArticleBizImpl")
+public class ArticleBizImpl extends BasicBizImpl implements IArticleBiz {
+
+	
+	/**
+	 * 文章持久化处理
+	 */
+	private IArticleDao articleDao;
+	
+	
+
+	/**
+	 * 栏目业务处理
+	 */
+	@Autowired
+	private ICategoryBiz categoryBiz; 
+
+	/**
+	 * 自定类型义业务处理
+	 */
+	@Autowired
+	private IColumnBiz columnBiz;
+	
+	/**
+	 * 自定义模型
+	 */
+	@Autowired
+	private IContentModelBiz contentModelBiz;
+	
+	/**
+	 * 模块管理业务层
+	 */
+	@Autowired
+	private IModelBiz modelBiz;
+
+	@Override
+	@Deprecated
+	public int count(int webId, int[] basicCategoryId, String flag, String noFlag,ArticleEntity article) {
+		return articleDao.count(webId, basicCategoryId, flag, noFlag,article);
+	}
+
+
+	/**
+	 * 获取Article的持久化层
+	 * 
+	 * @return 返回持Article的久化对象
+	 */
+	public IArticleDao getArticleDao() {
+		return articleDao;
+	}
+
+	@Override
+	@Deprecated
+	public ArticleEntity getByCategoryId(int categoryId) {
+		// TODO Auto-generated method stub
+		List list = articleDao.getByCategoryId(categoryId);
+		if (list != null && list.size() > 0) {
+			return (ArticleEntity) list.get(0);
+		}
+		return null;
+	}
+
+	@Override
+	public ArticleEntity getById(int basicId) {
+		// TODO Auto-generated method stub
+		ArticleEntity article = (ArticleEntity) articleDao.getEntity(basicId);
+		String contentModelTableName = null;
+		int ccmi = article.getColumn().getColumnContentModelId(); // 内容模型编号
+		if (ccmi > 0) {
+			ContentModelEntity contentModel = (ContentModelEntity) contentModelBiz.getEntity(ccmi);
+			contentModelTableName = contentModel.getCmTableName();
+		}
+		List temp = articleDao.getById(basicId, contentModelTableName);
+		if (temp != null && temp.size() > 0) {
+			return (ArticleEntity) temp.get(0);
+		}
+		return null;
+	}
+
+
+
+	/**
+	 * 获取IBaseDao的持久化层
+	 * 
+	 * @return 返回持articleDao的久化对象
+	 */
+	@Override
+	protected IBaseDao getDao() {
+		// TODO Auto-generated method stub
+		return articleDao;
+	}
+
+	@Override
+	@Deprecated
+	public ArticleEntity getNext(int appId, int basicId,Integer categoryId) {
+		// TODO Auto-generated method stub
+		return articleDao.getNextOrPrevious(appId, basicId, true,categoryId);
+	}
+
+	@Override
+	@Deprecated
+	public ArticleEntity getPrevious(int appId, int basicId,Integer categoryId) {
+		// TODO Auto-generated method stub
+		return articleDao.getNextOrPrevious(appId, basicId, false,categoryId);
+	}
+	@Override
+	@Deprecated
+	public int getSearchCount(ContentModelEntity contentModel,Map wherMap, int websiteId,List  ids) {
+		if (contentModel!=null) {
+			return articleDao.getSearchCount(contentModel.getCmTableName(),wherMap, websiteId,ids);
+		}
+		return articleDao.getSearchCount(null,wherMap, websiteId,ids);
+	}
+
+	@Override
+	public List<ArticleEntity> query(int webId, int[] basicCategoryIds, String flag, String noFlag, String orderBy,
+			boolean order,String beginTime,String endTime, ArticleEntity article) {
+		// TODO Auto-generated method stub
+		if(article == null) {
+			article = new ArticleEntity();
+		}
+		return articleDao.query(webId, basicCategoryIds, flag, noFlag, orderBy, order, beginTime, endTime, article);
+	}
+
+	/**
+	 * 根据页面栏目的id获取与其绑定的文章实体
+	 * 
+	 * @param basicCategoryId
+	 * @return 文章实体
+	 */
+	@Override
+	@Deprecated
+	public List<ArticleEntity> queryListByColumnId(int basicCategoryId) {
+		// TODO Auto-generated method stub
+		return articleDao.queryListByColumnId(basicCategoryId);
+	}
+
+
+	@Deprecated
+	public List<ArticleEntity> queryListForSearch(ContentModelEntity conntentModel, Map whereMap,  int websiteId,List ids,Map orders) {
+		List<ArticleEntity> articleList = new ArrayList<ArticleEntity>();
+		String tableName = null;
+		if (conntentModel!=null) {
+			tableName = conntentModel.getCmTableName();
+		}
+		// 查找所有符合条件的文章实体
+		articleList = articleDao.queryListForSearch(tableName, whereMap, websiteId,ids,orders);
+		return articleList;
+	}
+
+	/**
+	 * 设置Article的持久化层
+	 * 
+	 * @param articleDao
+	 */
+	@Autowired
+	public void setArticleDao(IArticleDao articleDao) {
+		this.articleDao = articleDao;
+	}
+
+
+	@Override
+	public List<ColumnArticleIdBean> queryIdsByCategoryIdForParser(int categoryId, String beginTime,String endTime) {
+		return this.articleDao.queryIdsByCategoryIdForParser(categoryId,BasicUtil.getAppId(), beginTime, endTime);
+	}
+}

+ 115 - 0
src/main/java/net/mingsoft/cms/constant/ModelCode.java

@@ -0,0 +1,115 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.constant;
+
+import net.mingsoft.base.constant.e.BaseEnum;
+
+public enum ModelCode implements BaseEnum{
+	/**
+	 * 内容:栏目模块编号
+	 */
+	CMS_COLUMN("02990000"),
+
+	/**
+	 * 内容:文章模块编号
+	 */
+	CMS_ARTICLE("02980100"),
+	/**
+	 * 内容:文章列表
+	 */
+	CMS_ARTICLE_BASIC("02980000"),
+	/**
+	 * 内容:自定义搜索
+	 */
+	CMS_SEARCH("02050000"),
+
+	/**
+	 * 内容:自定义模型
+	 */
+	CMS_CONTENT_MODEL("02060000"),
+
+	/**
+	 * 内容:一键更新
+	 */
+	CMS_GENERATE_ALL("02070100"),
+
+	/**
+	 * 内容:更新主页
+	 */
+	CMS_GENERATE_INDEX("02070200"),
+
+	/**
+	 * 内容:更新文档
+	 */
+	CMS_GENERATE_ARTICLE("02070300"),
+
+	/**
+	 * 内容: 更新栏目
+	 */
+	CMS_GENERATE_COLUMN("02070400"),
+
+	/**
+	 * 内容:模版
+	 */
+	CMS_TEMPLETSKIN("02080000"),
+	
+	
+	
+	/**
+	 * 内容:织梦数据导入
+	 */
+	COM_DEDE_DATA_IMPORT("02090100"),
+	
+	/**
+	 * 内容:栏目属性管理模块
+	 */
+	CMS_COLUMN_TYPE("02090200");
+	/**
+	 * 设置modelCode的常量
+	 * @param code 常量
+	 */
+	ModelCode(String code) {
+		this.code = code;
+	}
+
+	private String code;
+
+	/**
+	 * 返回该modelCode常量的字符串表示
+	 * @return 字符串
+	 */
+	@Override
+	public String toString() {
+		// TODO Auto-generated method stub
+		return code;
+	}
+
+	/**
+	 * 返回该modelCode常量的整型表示
+	 * @return 整型
+	 */
+	public int toInt() {
+		// TODO Auto-generated method stub
+		return Integer.parseInt(code);
+	}
+
+}

+ 59 - 0
src/main/java/net/mingsoft/cms/constant/e/ColumnTypeEnum.java

@@ -0,0 +1,59 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.constant.e;
+
+import net.mingsoft.base.constant.e.BaseEnum;
+
+/**
+ * 
+ * @ClassName:  ColumnTypeEnum   
+ * @Description:TODO(文章栏目分类类型)   
+ * @author: 铭飞开发团队
+ * @date:   2018年1月31日 下午2:55:18   
+ *     
+ * @Copyright: 2018 www.mingsoft.net Inc. All rights reserved.
+ */
+public enum ColumnTypeEnum implements BaseEnum {
+	/**
+	 * 列表
+	 */
+	COLUMN_TYPE_LIST(1),
+	/**
+	 * 单页
+	 */
+	COLUMN_TYPE_COVER(2),
+	/**
+	 * 跳转地址
+	 */
+	COLUMN_TYPE_URL(3);
+	ColumnTypeEnum(Object code) {
+		this.code = code;
+	}
+	
+	private Object code;
+	@Override
+	public int toInt() {
+		// TODO Auto-generated method stub
+		return Integer.valueOf(code+"");
+	}
+	
+}

+ 168 - 0
src/main/java/net/mingsoft/cms/dao/IArticleDao.java

@@ -0,0 +1,168 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.dao;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.annotations.Param;
+
+import net.mingsoft.cms.bean.ColumnArticleIdBean;
+import net.mingsoft.cms.entity.ArticleEntity;
+
+import net.mingsoft.base.dao.IBaseDao;
+
+
+/**
+ * 
+ * @ClassName:  IArticleDao   
+ * @Description:TODO(文章管理持久化层 || 继承IBaseDao持久化层)   
+ * @author: 铭飞开发团队
+ * @date:   2018年1月31日 下午2:55:33   
+ *     
+ * @Copyright: 2018 www.mingsoft.net Inc. All rights reserved.
+ */
+public interface IArticleDao extends IBaseDao {
+
+	/**
+	 * @para webId 网站编号
+	 * @param basicCategoryIds
+	 *            栏目编号集合
+	 * @param flag
+	 *            文章属性
+	 * @param noFlag
+	 *            文章不存在的属性
+	 * @param article
+	 *            文章实体,便于扩展查询
+	 * @return 文章总数
+	 */
+	@Deprecated
+	int count(@Param("webId") int webId, @Param("basicCategoryIds") int[] basicCategoryIds, @Param("flag") String flag,
+			@Param("noFlag") String noFlag, @Param("article") ArticleEntity article);
+
+	/**
+	 * 通过分类id获取文章内容
+	 * 
+	 * @param categoryId
+	 *            分类编号
+	 * @return 文章集合
+	 */
+	@Deprecated
+	List getByCategoryId(@Param("categoryId") int categoryId);
+
+	/**
+	 * 通过视图表来查询文章总数
+	 * 
+	 * @param basicId
+	 *            文章编号
+	 * @param contentModelTableName
+	 *            对应模块表名称
+	 */
+	List getById(@Param("basicId") int basicId, @Param("contentModelTableName") String contentModelTableName);
+
+	/**
+	 * 查找basicId上一篇文章
+	 * 
+	 * @param appId
+	 *            应用编号
+	 * @param basicId
+	 *            文章编号
+	 * @param flag
+	 *            true:上一条 false:下一条
+	 * @return
+	 */
+	ArticleEntity getNextOrPrevious(@Param("appId") int appId, @Param("basicId") int basicId,
+			@Param("flag") boolean flag, @Param("categoryId") Integer categoryId);
+
+	/**
+	 * 根据查询文章实体总数
+	 * 
+	 * @param tableName
+	 *            :自定义生成的表名
+	 * @param map
+	 *            key:字段名 value:List 字段的各种判断值 list[0]:是否为自定义字段 list[1]:是否为整形
+	 *            list[2]:是否是等值查询 list[3]:字段的值
+	 * @return 文章实体总数
+	 */
+	@Deprecated
+	int getSearchCount(@Param("tableName") String tableName, @Param("map") Map<String, List> map,
+			@Param("websiteId") int websiteId, @Param("ids") List ids);
+
+	/**
+	 * 文章查询
+	 * 
+	 * @para webId 网站编号
+	 * @param basicCategoryIds
+	 *            栏目编号集合
+	 * @param flag
+	 *            文章属性
+	 * @param noFlag
+	 *            文章不存在的属性
+	 * @param orderBy
+	 *            排序字段
+	 * @param order
+	 *            true 升序 false 降序 排序方式
+	 * @param article
+	 *            文章实体,便于扩展查询
+	 * @param beginTime 开始时间    
+	 * @param endTime 结束时间 
+	 * @return 文章集合
+	 */
+	List<ArticleEntity> query(@Param("webId") int webId, @Param("basicCategoryIds") int[] basicCategoryIds,
+			@Param("flag") String flag, @Param("noFlag") String noFlag, @Param("orderBy") String orderBy,
+			@Param("order") boolean order, @Param("beginTime") String beginTime,@Param("endTime") String endTime, 
+			@Param("article") ArticleEntity article);
+
+	/**
+	 * 根据页面栏目的id获取与其绑定的文章实体
+	 * 
+	 * @param basicCategoryId
+	 * @return 文章实体
+	 */
+	@Deprecated
+	List<ArticleEntity> queryListByColumnId(@Param("basicCategoryId") int basicCategoryId);
+
+	/**
+	 * 根据查询文章实体
+	 * 
+	 * @param tableName
+	 *            :自定义生成的表名
+	 * @param map
+	 *            获取查询条件的Map key:字段名 value:List 字段的各种判断值 list[0]:是否为自定义字段
+	 *            list[1]:是否为整形 list[2]:是否是等值查询 list[3]:字段的值
+	 * @return 文章实体
+	 */
+	@Deprecated
+	List<ArticleEntity> queryListForSearch(@Param("tableName") String tableName, @Param("map") Map<String, List> map,
+			 @Param("websiteId") int websiteId, @Param("ids") List ids,
+			@Param("sortMap") Map sortMap);
+
+	/**
+	 * 查询文章编号集合
+	 * @param categoryId 栏目编号
+	 * @param appId 站点编号
+	 * @param beginTime 开始时间
+	 * @param endTime 结束时间
+	 * @return
+	 */
+	public List<ColumnArticleIdBean> queryIdsByCategoryIdForParser(@Param("categoryId")int categoryId,@Param("appId")int appId , @Param("beginTime") String beginTime,@Param("endTime") String endTime);
+}

+ 616 - 0
src/main/java/net/mingsoft/cms/dao/IArticleDao.xml

@@ -0,0 +1,616 @@
+<?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="net.mingsoft.cms.dao.IArticleDao">
+	<!-- 表栏目名 开始 -->
+	<sql id="column_list">
+		a.ARTICLE_BASICID,a.ARTICLE_CONTENT,a.ARTICLE_AUTHOR,a.ARTICLE_TYPE,a.ARTICLE_SOURCE,a.ARTICLE_URL,a.ARTICLE_KEYWORD,a.ARTICLE_FREEORDER,a.ARTICLE_WEBID,
+		b.BASIC_ID,b.BASIC_TITLE,b.BASIC_DESCRIPTION,b.BASIC_THUMBNAILS,b.BASIC_HIT,b.BASIC_DISPLAY,b.BASIC_DATETIME,b.BASIC_UPDATETIME,b.BASIC_PEOPLEID,b.BASIC_CATEGORYID,b.BASIC_SORT
+	</sql>
+	<!-- 表栏目名 结束 -->
+
+
+	<!-- 获取表字段 开始 -->
+	<resultMap type="net.mingsoft.cms.entity.ArticleEntity" id="resultMap">
+		<id column="ARTICLE_BASICID" property="articleID" />				<!-- 与cms_article表绑定id -->
+		<result column="ARTICLE_CONTENT" property="articleContent" />	<!-- 文章内容 -->
+		<result column="ARTICLE_AUTHOR" property="articleAuthor" />		<!-- 文章作者 -->
+		<result column="ARTICLE_TYPE" property="articleType" />			<!-- 文章属性 -->
+		<result column="ARTICLE_SOURCE" property="articleSource" />		<!-- 文章来源 -->
+		<result column="ARTICLE_URL" property="articleUrl" />			<!-- 文章跳转链接地址 -->
+		<result column="ARTICLE_KEYWORD" property="articleKeyword" />	<!-- 文章关键字 -->
+		<result column="ARTICLE_FREEORDER" property="articleFreeOrder" /><!-- 
+			文章自定义显示顺序 -->
+		<result column="ARTICLE_WEBID" property="articleWebId" />				<!-- 站点id -->
+		<result column="BASIC_ID" property="basicId" />					<!-- 与表basic绑定 自增长ID -->
+		<result column="BASIC_TITLE" property="basicTitle" />			<!-- 文章标题 -->
+		<result column="BASIC_DESCRIPTION" property="basicDescription" /><!-- 
+			文章描述 -->
+		<result column="BASIC_THUMBNAILS" property="basicThumbnails" />	<!-- 文章缩略图 -->
+		<result column="BASIC_HIT" property="basicHit" />				<!-- 文章点击次数 -->
+		<result column="BASIC_DATETIME" property="basicDateTime" />		<!-- 文章发布时间 -->
+		<result column="BASIC_UPDATETIME" property="basicUpdateTime" />	<!-- 文章更新时间 -->
+		<result column="BASIC_PEOPLEID" property="basicPeopleId" />		<!-- 文章发布者id -->
+		<result column="BASIC_CATEGORYID" property="basicCategoryId" />	<!-- 文章所属主栏目id -->
+		<result column="BASIC_SORT" property="basicSort" />
+		<result column="BASIC_DISPLAY" property="basicDisplay" />
+		<!-- 一对一关联栏目 -->
+		<association property="column" column="COLUMN_CATEGORY_ID"
+			javaType="net.mingsoft.basic.entity.ColumnEntity">
+			<result property="columnPath" column="column_path" />
+			<result property="categoryTitle" column="category_title" />
+			<result property="categoryId" column="category_id" />
+			<result property="columnContentModelId" column="COLUMN_CM_ID" />
+			<result property="columnType" column="COLUMN_TYPE" />
+		</association>
+	</resultMap>
+	<!-- 获取表字段 结束 -->
+	<!-- 通过视图查询返回结果集 开始 -->
+	<resultMap type="net.mingsoft.cms.bean.ColumnArticleIdBean" id="resultMapBean">
+		<result column="ARTICLE_BASICID" property="articleId" />	
+		<result column="column_path" property="columnPath"/>			
+		<result column="column_url" property="columnUrl" />
+		<result column="category_title" property="categoryTitle" />
+		<result column="category_id" property="categoryId" />
+		<result column="COLUMN_CM_ID" property="columnContentModelId" />
+		<result column="COLUMN_TYPE" property="columnType" />
+	</resultMap>
+	<!-- 通过视图查询返回结果集 结束 -->
+	<!-- 通过视图查询返回结果集 开始 -->
+	<resultMap type="net.mingsoft.cms.entity.ArticleEntity" id="viewResultMap">
+		<id column="ARTICLE_BASICID" property="articleID" />				<!-- 与cms_article表绑定id -->
+		<result column="ARTICLE_CONTENT" property="articleContent" />	<!-- 文章内容 -->
+		<result column="ARTICLE_AUTHOR" property="articleAuthor" />		<!-- 文章作者 -->
+		<result column="ARTICLE_TYPE" property="articleType" />			<!-- 文章属性 -->
+		<result column="ARTICLE_SOURCE" property="articleSource" />		<!-- 文章来源 -->
+		<result column="ARTICLE_URL" property="articleUrl" />			<!-- 文章跳转链接地址 -->
+		<result column="ARTICLE_KEYWORD" property="articleKeyword" />	<!-- 文章关键字 -->
+		<result column="ARTICLE_FREEORDER" property="articleFreeOrder" /><!-- 
+			文章自定义显示顺序 -->
+		<result column="ARTICLE_WEBID" property="articleWebId" />				<!-- 站点id -->
+
+		<result column="BASIC_ID" property="basicId" />					<!-- 与表basic绑定 自增长ID -->
+		<result column="BASIC_TITLE" property="basicTitle" />			<!-- 文章标题 -->
+		<result column="BASIC_DESCRIPTION" property="basicDescription" /><!-- 
+			文章描述 -->
+		<result column="BASIC_THUMBNAILS" property="basicThumbnails" />	<!-- 文章缩略图 -->
+		<result column="BASIC_HIT" property="basicHit" />				<!-- 文章点击次数 -->
+		<result column="BASIC_DATETIME" property="basicDateTime" />		<!-- 文章发布时间 -->
+		<result column="BASIC_UPDATETIME" property="basicUpdateTime" />	<!-- 文章更新时间 -->
+		<result column="BASIC_CATEGORYID" property="basicCategoryId" />	<!-- 文章所属主栏目id -->
+		<result column="BASIC_SORT" property="basicSort" />
+		<result column="BASIC_DISPLAY" property="basicDisplay" />
+		<!-- 一对一关联栏目 -->
+		<association property="column"
+			javaType="net.mingsoft.basic.entity.ColumnEntity">
+			<result property="columnPath" column="column_path" />
+			<result property="categoryTitle" column="category_title" />
+			<result property="categoryId" column="category_id" />
+			<result property="columnContentModelId" column="COLUMN_CM_ID" />
+			<result property="columnType" column="COLUMN_TYPE" />
+		</association>
+	</resultMap>
+	<!-- 通过视图查询返回结果集 结束 -->
+
+	<!-- 文章bean返回数据列表 开始 -->
+	<sql id="bean_column_list">
+		BASIC_ID,ARTICLE_AUTHOR,ARTICLE_TYPE,ARTICLE_SOURCE,ARTICLE_URL,ARTICLE_KEYWORD,ARTICLE_FREEORDER,
+		BASIC_DISPLAY,BASIC_TITLE,BASIC_DESCRIPTION,BASIC_THUMBNAILS,BASIC_HIT,BASIC_DATETIME,BASIC_UPDATETIME,BASIC_PEOPLEID,BASIC_CATEGORYID,BASIC_SORT
+	</sql>
+	<!-- 表栏目名结束 -->
+	
+	<!-- 文章基础数据返回数据列表 开始 -->
+	<sql id="basic_data_list">
+		BASIC_DISPLAY,BASIC_ID,BASIC_CATEGORYID,BASIC_TITLE,BASIC_DESCRIPTION,BASIC_THUMBNAILS,BASIC_HIT,BASIC_DATETIME,BASIC_UPDATETIME,BASIC_PEOPLEID,BASIC_SORT,
+		ARTICLE_BASICID,ARTICLE_AUTHOR,ARTICLE_CONTENT,ARTICLE_TYPE,ARTICLE_SOURCE,ARTICLE_URL,ARTICLE_KEYWORD,ARTICLE_FREEORDER,ARTICLE_WEBID,
+		COLUMN_KEYWORD,COLUMN_DESCRIP,COLUMN_TYPE,COLUMN_URL,COLUMN_LISTURL,COLUMN_PATH,COLUMN_CM_ID,COLUMN_CATEGORY_ID,
+		CATEGORY_TITLE,CATEGORY_APPID,CATEGORY_ID
+	</sql>
+	<!-- 文章基础数据返回数据列表结束 -->
+
+	<!-- 添加文章信息 开始 -->
+	<insert id="saveEntity" parameterType="net.mingsoft.base.entity.BaseEntity">
+		insert into cms_article
+		<!-- 添加表字段 -->
+		<trim prefix="(" suffix=")" suffixOverrides=",">
+			<if test="basicId != null">ARTICLE_BASICID,</if>
+			<if test="articleContent != null">ARTICLE_CONTENT,</if>
+			<if test="articleAuthor != null">ARTICLE_AUTHOR,</if>
+			<if test="articleType != null">ARTICLE_TYPE,</if>
+			<if test="articleSource != null">ARTICLE_SOURCE,</if>
+			<if test="articleUrl != null">ARTICLE_URL,</if>
+			<if test="articleKeyword != null">ARTICLE_KEYWORD,</if>
+			<if test="articleFreeOrder != null">ARTICLE_FREEORDER,</if>
+			<if test="articleWebId != null">ARTICLE_WEBID,</if>
+		</trim>
+		<!-- 注入控制层字段 -->
+		<trim prefix="values (" suffix=")" suffixOverrides=",">
+			<if test="basicId != null">#{basicId},</if>
+			<if test="articleContent != null">#{articleContent},</if>
+			<if test="articleAuthor != null">#{articleAuthor},</if>
+			<if test="articleType != null">#{articleType},</if>
+			<if test="articleSource != null">#{articleSource},</if>
+			<if test="articleUrl != null">#{articleUrl},</if>
+			<if test="articleKeyword != null">#{articleKeyword},</if>
+			<if test="articleFreeOrder != null">#{articleFreeOrder},</if>
+			<if test="articleWebId != null">#{articleWebId},</if>
+		</trim>
+	</insert>
+	<!-- 添加文章信息 结束 -->
+
+	<!-- 删除文章管理的信息 开始 -->
+	<delete id="deleteEntity" parameterType="int">
+		DELETE b from basic b WHERE b.basic_id=#{basicId};
+		DELETE c from cms_article c WHERE c.article_basicid=#{basicId}
+	</delete>
+	<!-- 删除文章管理的信息 结束 -->
+
+	<!-- 更新文章管理的信息 开始 -->
+	<update id="updateEntity" parameterType="net.mingsoft.base.entity.BaseEntity">
+		update cms_article
+		<set>
+			<if test="articleContent != null">ARTICLE_CONTENT=#{articleContent},</if>
+			<if test="articleAuthor != null">ARTICLE_AUTHOR=#{articleAuthor},</if>
+			<if test="articleType != null">ARTICLE_TYPE=#{articleType},</if>
+			<if test="articleSource != null">ARTICLE_SOURCE=#{articleSource},</if>
+			<if test="articleUrl != null">ARTICLE_URL=#{articleUrl},</if>
+			<if test="articleKeyword != null">ARTICLE_KEYWORD=#{articleKeyword},</if>
+			<if test="articleFreeOrder != null">ARTICLE_FREEORDER=#{articleFreeOrder},</if>
+			<if test="articleWebId != null">ARTICLE_WEBID=#{articleWebId},</if>
+		</set>
+		where ARTICLE_BASICID = #{basicId}
+	</update>
+	<!-- 更新文章管理的信息 开始 -->
+
+
+	<!-- 查找文章管理的信息 开始 -->
+	<select id="getEntity" resultMap="resultMap" parameterType="int">
+		select
+		<include refid="column_list" />
+		,c.CATEGORY_TITLE,cl.column_path,cl.column_type,c.CATEGORY_id,cl.COLUMN_CM_ID
+		FROM
+		basic b
+		LEFT JOIN
+		category c ON b.BASIC_CATEGORYID = c.CATEGORY_ID
+		LEFT JOIN basic_column
+		cl ON c.CATEGORY_ID = cl.COLUMN_CATEGORY_ID
+		LEFT
+		JOIN cms_article a ON
+		a.ARTICLE_BASICID = b.BASIC_ID
+
+		<!-- 查询与关联表id相同的信息 -->
+
+		where a.ARTICLE_BASICID=#{basicId}
+	</select>
+	<!-- 查找文章管理的信息 结束 -->
+	
+	<!-- 标题字段query -->
+	<sql id="queryWhereBasicTitle" databaseId="mysql">
+		CONCAT('%',#{article.basicTitle},'%') 
+	</sql>
+	<sql id="queryWhereBasicTitle" databaseId="oracle">
+		'%'||#{ article.basicTitle}||'%'
+	</sql>
+	<sql id="queryWhereBasicTitle" databaseId="sqlServer">
+		'%'+#{ article.basicTitle}+'%'
+	</sql>
+	<!-- flag字段 -->
+	<sql id="queryWhereFlag" databaseId="mysql">
+		CONCAT('%',#{flag},'%') 
+	</sql>
+	<sql id="queryWhereFlag" databaseId="oracle">
+		'%'||#{ flag}||'%'
+	</sql>
+	<sql id="queryWhereFlag" databaseId="sqlServer">
+		'%'+#{ flag}+'%'
+	</sql>
+	<!-- noFlag字段 -->
+	<sql id="queryWhereNoFlag" databaseId="mysql">
+		CONCAT('%',#{noFlag},'%') 
+	</sql>
+	<sql id="queryWhereNoFlag" databaseId="oracle">
+		'%'||#{ noFlag}||'%'
+	</sql>
+	<sql id="queryWhereNoFlag" databaseId="sqlServer">
+		'%'+#{ noFlag}+'%'
+	</sql>
+	<!-- 已过期 -->
+	<select id="count" resultType="int">
+		select count(basic_id) FROM basic b
+		LEFT JOIN category c ON
+		b.BASIC_CATEGORYID = c.CATEGORY_ID
+		LEFT JOIN basic_column cl ON
+		c.CATEGORY_ID = cl.COLUMN_CATEGORY_ID
+		LEFT JOIN cms_article a ON
+		a.ARTICLE_BASICID = b.BASIC_ID
+		<where>
+			a.ARTICLE_WEBID = #{webId}
+			<if test="article != null ">
+				<if test="article.basicTitle != null and article.basicTitle != ''">
+					and b.BASIC_TITLE like
+					<include refid="queryWhereBasicTitle"></include>
+				</if>
+			</if>
+			<if test="basicCategoryIds != null">
+				and b.BASIC_CATEGORYID in
+				<foreach collection="basicCategoryIds" index="index" item="categoryId"
+					open="(" separator="," close=")">
+					#{categoryId}
+				</foreach>
+			</if>
+			<if test="flag != null">
+				and a.ARTICLE_TYPE like <include refid="queryWhereFlag"></include>
+			</if>
+			<if test="noFlag != null">
+				and a.ARTICLE_TYPE not like <include refid="queryWhereNoFlag"></include>
+			</if>
+		</where>
+	</select>
+	<!-- 列表查询结束 -->
+	
+	<!-- 列表查询开始 -->
+	<select id="query" resultMap="resultMap" >
+		select
+		<include refid="column_list" />
+		,c.CATEGORY_TITLE,c.CATEGORY_ID
+		,cl.COLUMN_PATH,cl.COLUMN_CM_ID,cl.COLUMN_TYPE,cl.COLUMN_CATEGORY_ID 
+		FROM cms_article a LEFT JOIN basic b  ON a.ARTICLE_BASICID = b.BASIC_ID 
+		LEFT JOIN basic_column cl ON b.BASIC_CATEGORYID = cl.COLUMN_CATEGORY_ID 
+		JOIN category c ON c.CATEGORY_ID = cl.COLUMN_CATEGORY_ID
+		where a.ARTICLE_WEBID = #{webId}
+		<if test="article != null ">
+			<if test="article.basicTitle != null and article.basicTitle != ''">
+				and b.BASIC_TITLE like
+				<include refid="queryWhereBasicTitle"></include>
+			</if>
+		</if>
+		<if test="basicCategoryIds != null">
+			and b.BASIC_CATEGORYID in
+			<foreach collection="basicCategoryIds" index="index" item="categoryId"
+				open="(" separator="," close=")">
+				#{categoryId}
+			</foreach>
+		</if>
+		<if test="flag != null">
+			and a.ARTICLE_TYPE like <include refid="queryWhereFlag"></include>
+		</if>
+		<if test="noFlag != null">
+			and a.ARTICLE_TYPE not like <include refid="queryWhereNoFlag"></include>
+		</if>
+		<if test="article !=null and article.basicDisplay &gt; -1">
+			and b.basic_display = #{article.basicDisplay}
+		</if>
+		<if test="beginTime!=null and beginTime!=''">
+			and basic_updatetime &gt;= #{beginTime}
+		</if>
+		<if test="endTime!=null and endTime!=''">
+			and basic_updatetime &gt;= #{endTime}
+		</if>
+		<if test="orderBy != null">
+			order by
+			<choose>
+				<when test='orderBy=="sort"'>basic_sort</when>
+				<when test='orderBy=="date"'>basic_datetime</when>
+				<when test='orderBy=="hit"'>basic_hit</when>
+				<when test='orderBy=="updatedate"'>basic_updatedate</when>
+				<when test='orderBy=="id"'>basic_id</when>
+				<otherwise>
+					${orderBy}
+				</otherwise>
+			</choose>
+		</if>
+		<if test="orderBy==null">
+			order by b.basic_id
+		</if>
+		<if test="order == true">desc</if>
+		<if test="order == false">asc</if>
+	</select>
+
+	<!-- 根据站点编号、开始、结束时间和栏目编号查询文章编号集合 -->
+	<select id="queryIdsByCategoryIdForParser" resultMap="resultMapBean" >
+		select
+		ARTICLE_BASICID,cl.*
+		FROM cms_article a LEFT JOIN basic b  ON a.ARTICLE_BASICID = b.BASIC_ID 
+		LEFT JOIN basic_column cl ON b.BASIC_CATEGORYID = cl.COLUMN_CATEGORY_ID 
+		JOIN category c ON c.CATEGORY_ID = cl.COLUMN_CATEGORY_ID
+		where 
+		<if test="appId &gt; 0">
+			a.ARTICLE_WEBID = #{appId}
+		</if>
+		<!-- 查询子栏目数据 -->
+		<if test="categoryId &gt; 0">
+			and (b.basic_categoryid=#{categoryId} or b.basic_categoryid in 
+				(select category_id FROM category where find_in_set(#{categoryId},CATEGORY_PARENT_ID)))
+		</if>
+		<if test="beginTime!=null and beginTime!=''">
+			and b.basic_updatetime &gt;= #{beginTime}
+		</if>
+		<if test="endTime!=null and endTime!=''">
+			and b.basic_updatetime &gt;= #{endTime}
+		</if>
+	</select>
+
+
+
+	<!--查询页面栏目的文章 开始 -->
+	<!-- 已过期 -->
+	<select id="queryListByColumnId" resultMap="resultMap">
+		select
+		<include refid="column_list" />
+		from cms_article a left join basic b on b.basic_id=a.ARTICLE_BASICID
+		where b.BASIC_CATEGORYID = #{basicCategoryId}
+	</select>
+	<!-- 查询页面栏目的文章 结束 -->
+
+
+
+
+	<!-- 根据字段条件查找文章实体开始 -->
+	<sql id="queryLike" databaseId="mysql">
+		like CONCAT("%",
+			<foreach item="val" index="index" collection="item[3]">
+				<if test="index==0">#{val}</if>
+			</foreach>
+			,"%")
+	</sql>
+	<sql id="queryLike" databaseId="oracle">
+		like '%'||
+			<foreach item="val" index="index" collection="item[3]">
+				<if test="index==0">#{val}</if>
+			</foreach>
+			||'%')
+	</sql>
+	<sql id="queryLike" databaseId="sqlServer">
+		like '%'+
+			<foreach item="val" index="index" collection="item[3]">
+				<if test="index==0">#{val}</if>
+			</foreach>
+			 +'%')
+	</sql>
+	<!-- 已过期 -->
+	<select id="queryListForSearch" resultMap="resultMap">
+		select
+		<include refid="column_list" />
+		,c.CATEGORY_TITLE,cl.column_path,c.CATEGORY_id,cl.COLUMN_CM_ID,cl.column_type
+		from cms_article a
+		left join basic b
+		on b.basic_id=a.ARTICLE_BASICID
+		left join category c
+		ON b.BASIC_CATEGORYID = c.CATEGORY_ID
+		left join
+		basic_column cl
+		on c.CATEGORY_ID = cl.COLUMN_CATEGORY_ID
+		<if test="tableName!=null">left join ${tableName} d on d.basicId=a.ARTICLE_BASICID
+		</if>
+		where c.DEL=0 and a.ARTICLE_WEBID = #{websiteId}
+		<if test="ids!=null">
+			and
+			b.BASIC_CATEGORYID in
+			<foreach item="id" index="key" collection="ids" open="("
+				separator="," close=")">
+				#{id.categoryId}
+			</foreach>
+		</if>
+		<foreach item="item" index="key" collection="map" open=""
+			separator="" close="">
+			<if test=" item[0] == false">
+				and ${key}
+			</if>
+			<if test="item[0]== true">
+				and d.${key}
+			</if>
+			<!-- 数字类型的查找 item[1]:字段是否为数字类型false:数字 -->
+			<if test="item[1] == false">
+				<!--item[2]: 是采用等值还是区间查询。false:区间 itme[3][0]第一个值item[3][1]的二个值 -->
+				<if test="item[2] == true">
+					=
+					<foreach item="val" index="index" collection="item[3]">#{val}
+					</foreach>
+				</if>
+				<if test="item[2] == false">
+					between
+					<foreach item="val" index="index" collection="item[3]"
+						separator="and">
+						#{val}
+					</foreach>
+				</if>
+			</if>
+			<!-- 字符型数据的查找 item[1]:字段是否为数字类型true:字符串 -->
+			<if test="item[1] == true">
+				<!--item[2]: 是采用模糊查询。false:不采用模糊 -->
+				<if test="item[2] == true">
+					<include refid="queryLike"></include>
+				</if>
+				<if test="item[2] == false">
+					=
+					<foreach item="val" index="index" collection="item[3]">#{val}
+					</foreach>
+				</if>
+			</if>
+		</foreach>
+		<if test="sortMap!=null">
+			order by ${sortMap.order} ${sortMap.by}
+		</if>
+	</select>
+	<!-- 根据字段条件查找文章实体结束 -->
+
+	<!--已过期 根据字段条件查找文章实体总数开始 -->
+	<select id="getSearchCount" resultType="int">
+		select count(*) from
+		cms_article a
+		left join basic b
+		on
+		b.basic_id=a.ARTICLE_BASICID
+		left join category c
+		ON b.BASIC_CATEGORYID
+		= c.CATEGORY_ID
+		left join basic_column cl
+		on c.CATEGORY_ID =
+		cl.COLUMN_CATEGORY_ID
+		<if test="tableName!=null">left join ${tableName} d on d.basicId=a.ARTICLE_BASICID
+		</if>
+		where a.ARTICLE_WEBID = #{websiteId} 
+
+		<if test="ids!=null">
+			and
+			b.BASIC_CATEGORYID in
+			<foreach item="id" index="key" collection="ids" open="("
+				separator="," close=")">
+				#{id.categoryId}
+			</foreach>
+		</if>
+
+		<foreach item="item" index="key" collection="map" open=""
+			separator="" close="">
+			<if test=" item[0] == false">
+				and ${key}
+			</if>
+			<if test="item[0]== true">
+				and d.${key}
+			</if>
+			<!-- 数字类型的查找 item[1]:字段是否为数字类型false:数字 -->
+			<if test="item[1] == false">
+				<!--item[2]: 是采用等值还是区间查询。false:区间 itme[3][0]第一个值item[3][1]的二个值 -->
+				<if test="item[2] == true">
+					=
+					<foreach item="val" index="index" collection="item[3]">#{val}
+					</foreach>
+				</if>
+				<if test="item[2] == false">
+					between
+					<foreach item="val" index="index" collection="item[3]"
+						separator="and">
+						#{val}
+					</foreach>
+				</if>
+			</if>
+			<!-- 字符型数据的查找 item[1]:字段是否为数字类型true:字符串 -->
+			<if test="item[1] == true">
+				<!--item[2]: 是采用模糊查询。false:不采用模糊 -->
+				<if test="item[2] == true">
+					<include refid="queryLike"></include>
+				</if>
+				<if test="item[2] == false">
+					=
+					<foreach item="val" index="index" collection="item[3]">#{val}
+					</foreach>
+				</if>
+			</if>
+		</foreach>
+	</select>
+	<!-- 根据字段条件查找文章实体总数结束 -->
+
+	<select id="getById" resultMap="viewResultMap">
+		select 
+		<include refid="basic_data_list" /> 
+		from 
+		(((basic JOIN cms_article ON (BASIC_ID = ARTICLE_BASICID))
+			JOIN basic_column ON (BASIC_CATEGORYID = COLUMN_CATEGORY_ID))
+			JOIN category ON (COLUMN_CATEGORY_ID = CATEGORY_ID))
+		<if test="contentModelTableName!=null">
+			left join ${contentModelTableName} cmt on
+			cmt.basicid=basic_id
+		</if>
+		where basic_id=#{basicId}
+	</select>
+
+
+	<!-- 通过文章标题、应用ID、模块编号来查询文章集合开始 -->
+	<resultMap type="java.util.HashMap" id="resultTitleMap">
+		<result column="basic_id" property="basicId" />
+		<result column="basic_title" property="basicTitle" />
+		<result column="basic_hit" property="basicHit" />
+		<result column="basic_categoryid" property="basicCategoryId" />
+		<result column="model_id" property="modelId" />
+
+	</resultMap>
+	<!-- 已过期 -->
+	<!-- 查找上一篇下一篇 -->
+	<sql id="selectOne">
+		from 
+		(((basic JOIN cms_article ON (BASIC_ID = ARTICLE_BASICID))
+			JOIN basic_column ON (BASIC_CATEGORYID = COLUMN_CATEGORY_ID))
+			JOIN category ON (COLUMN_CATEGORY_ID = CATEGORY_ID))
+		
+		 where category_appid=#{appId}
+		<if test="flag==false">
+			and basic_id &lt; ${basicId}
+
+		</if>
+		<if test="flag==true">
+			and basic_id &gt; ${basicId}
+
+		</if>
+		<if test="categoryId!=null">
+			and BASIC_CATEGORYID = #{categoryId}
+		</if>
+	</sql>
+	<!-- 已过期 -->
+	<select id="getNextOrPrevious" resultMap="resultMap" databaseId="mysql">
+		select 
+		<include refid="basic_data_list" />
+		<include refid="selectOne"></include>
+		<if test="flag==false">
+			order by basic_id desc
+		</if>
+		<if test="flag==true">
+			order by basic_id asc
+		</if>
+		limit 0,1
+	</select>
+	<!-- 已过期 -->
+	<select id="getNextOrPrevious" resultMap="resultMap" databaseId="oracle">
+		select 
+		<include refid="basic_data_list" />
+		<include refid="selectOne"></include>
+		and rownum=1
+		<if test="flag==false">
+			order by basic_id desc
+		</if>
+		<if test="flag==true">
+			order by basic_id asc
+		</if>
+	</select>
+	<!-- 已过期 -->
+	<select id="getNextOrPrevious" resultMap="resultMap" databaseId="sqlServer">
+		select top(1)
+		<include refid="basic_data_list" />
+		<include refid="selectOne"></include>
+		<if test="flag==false">
+			order by basic_id desc
+		</if>
+		<if test="flag==true">
+			order by basic_id asc
+		</if>
+	</select>
+	<sql id="queryTime" databaseId="oracle">
+		to_date(#{dateTime},'yyyy-MM-dd HH24:mi:ss')
+	</sql>
+	<sql id="queryTime" databaseId="mysql">
+		#{dateTime}
+	</sql>
+	<sql id="queryTime" databaseId="sqlServer">
+		#{dateTime}
+	</sql>
+	<!-- 已过期 -->
+	<select id="getByCategoryId" resultMap="resultMap">
+		select 
+		<include refid="basic_data_list" />
+		 from 
+		(((basic JOIN cms_article ON (BASIC_ID = ARTICLE_BASICID))
+			JOIN basic_column ON (BASIC_CATEGORYID = COLUMN_CATEGORY_ID))
+			JOIN category ON (COLUMN_CATEGORY_ID = CATEGORY_ID))
+		where basic_categoryId=#{categoryId} order by basic_id desc 
+	</select>
+
+	<!-- 根据basicID删除开始 -->
+	<delete id="delete">
+		delete from cms_article
+		<where>
+			ARTICLE_BASICID in
+			<foreach collection="ids" item="item" index="index" open="("
+				separator="," close=")">#{item}</foreach>
+		</where>
+	</delete>
+
+</mapper>

+ 293 - 0
src/main/java/net/mingsoft/cms/entity/ArticleEntity.java

@@ -0,0 +1,293 @@
+/**
+The MIT License (MIT) * Copyright (c) 2016 铭飞科技(mingsoft.net)
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.mingsoft.cms.entity;
+
+import java.io.File;
+import java.util.Arrays;
+
+import net.mingsoft.basic.entity.AppEntity;
+import net.mingsoft.basic.entity.BasicEntity;
+import net.mingsoft.basic.entity.ColumnEntity;
+import org.apache.commons.lang3.StringUtils;
+
+import cn.hutool.core.util.ArrayUtil;
+import net.mingsoft.base.constant.Const;
+import net.mingsoft.mdiy.util.ParserUtil;
+
+/**
+ * 
+ * @ClassName:  ArticleEntity   
+ * @Description:TODO(文章模块实体类 || 继承BasicEntity实体)   
+ * @author: 铭飞开发团队
+ * @date:   2018年1月31日 下午2:55:48   
+ *     
+ * @Copyright: 2018 www.mingsoft.net Inc. All rights reserved.
+ */
+public class ArticleEntity extends BasicEntity{
+	
+	/**
+	 * 文章Id
+	 */
+	private int articleID;
+	
+	/**
+	 * 文章内容
+	 */
+	private String articleContent;
+	
+	/**
+	 * 文章作者
+	 */
+	private String articleAuthor;
+	
+	/**
+	 * 文章属性
+	 */
+	private String articleType ;
+	
+	/**
+	 * 文章的来源
+	 */
+	private String articleSource;
+
+	/**
+	 * 文章跳转链接地址
+	 */
+	private String articleUrl;
+	
+	/**
+	 * 文章关键字
+	 */
+	private String articleKeyword;
+	
+	/**
+	 * 文章自定义显示顺序
+	 */
+	@Deprecated
+	private int articleFreeOrder;
+	
+	
+	/**
+	 * 站点d
+	 */
+	private int articleWebId;
+	
+	/**
+	 * 文章url地址 主要是用户生成html使用
+	 */
+	private String articleLinkURL;
+	
+	/**
+	 * 文章分类url地址,主要是用户生成html使用
+	 */
+	private String articleTypeLinkURL;
+	
+	/**
+	 * 一对一管理栏目
+	 */
+	private ColumnEntity  column;
+	
+	
+	/**
+	 * 获取文章实体所属的栏目实体
+	 * @return
+	 */
+	public ColumnEntity getColumn() {
+		return column;
+	}
+	
+	/**
+	 * 设置文章所属的栏目实体
+	 * @param column
+	 */
+	public void setColumn(ColumnEntity column) {
+		this.column = column;
+	}
+
+	public String getArticleTypeLinkURL() {
+		return articleTypeLinkURL;
+	}
+
+	public void setArticleTypeLinkURL(String articleTypeLinkURL) {
+		this.articleTypeLinkURL = articleTypeLinkURL;
+	}
+
+	public String getArticleLinkURL() {
+		return articleLinkURL;
+	}
+
+	public void setArticleLinkURL(String articleLinkURL) {
+		this.articleLinkURL = articleLinkURL;
+	}
+
+	/**
+	 * 获取文章作者
+	 * @return 返回文章作者
+	 */
+	public String getArticleAuthor() {
+		return articleAuthor;
+	}
+
+	/**
+	 * 获取文章内容
+	 * @return 返回文章内容
+	 */
+	public String getArticleContent() {
+		return articleContent;
+	}
+
+	/**
+	 * 获取自定义显示顺序
+	 * @return
+	 */
+	public int getArticleFreeOrder() {
+		return articleFreeOrder;
+	}
+	
+	/**
+	 * 获取文章Id
+	 * @return 返回文章Id
+	 */
+	public int getArticleID() {
+		return articleID;
+	}
+	
+	/**
+	 * 获取文章关键字
+	 * @return 返回文章关键字
+	 */
+	public String getArticleKeyword() {
+		return articleKeyword;
+	}
+	
+	/**
+	 * 获取文章的来源
+	 * @return 返回文章的来源
+	 */
+	public String getArticleSource() {
+		return articleSource;
+	}
+	
+	/**
+	 * 获取文章属性
+	 * @return 返回文章属性
+	 */
+	public String getArticleType() {
+		return articleType;
+	}
+	
+	/**
+	 * 获取文章跳转链接
+	 * @return 返回文章跳转链接
+	 */
+	public String getArticleUrl() {
+		return articleUrl; 
+	}
+	
+	/**
+	 * 获取文章站点id
+	 * @return
+	 */
+	public int getArticleWebId() {
+		return articleWebId;
+	}
+	
+	/**
+	 * 设置文章作者
+	 * @param articleAuthor 传入文章作者
+	 */
+	public void setArticleAuthor(String articleAuthor) {
+		this.articleAuthor = articleAuthor;
+	}
+	
+	/**
+	 * 设置文章内容
+	 * @param articleContent 传入文章内容
+	 */
+	public void setArticleContent(String articleContent) {
+		this.articleContent = articleContent;
+	}
+	
+	/**
+	 * 设置文章自定义显示循序排序
+	 * @param articleFreeOrder
+	 */
+	public void setArticleFreeOrder(int articleFreeOrder) {
+		this.articleFreeOrder = articleFreeOrder;
+	}
+
+	/**
+	 * 设置文章Id
+	 * @param articleID 传入文章Id
+	 */
+	public void setArticleID(int articleID) {
+		this.articleID = articleID;
+	}
+
+	/**
+	 * 设置文章关键字
+	 * @param articleKeyword 传入文章关键字列表
+	 */
+	public void setArticleKeyword(String articleKeyword) {
+		this.articleKeyword = articleKeyword;
+	}
+
+	/**
+	 * 设置文章的来源
+	 * @param articleSource 传入文章的来源
+	 */
+	public void setArticleSource(String articleSource) {
+		this.articleSource = articleSource;
+	}
+
+	/**
+	 * 设置文章属性
+	 * @param articleType 传入文章属性
+	 */
+	public void setArticleType(String articleType) {
+		this.articleType = articleType;
+	}
+	
+	/**
+	 * 设置文章跳转链接
+	 * @param articleUrl 传入文章跳转链接地址
+	 */
+	public void setArticleUrl(String articleUrl) {
+		this.articleUrl = articleUrl;
+	}
+
+
+	/**
+	 * 设置文章站点id
+	 * @param articleWebId
+	 */
+	public void setArticleWebId(int articleWebId) {
+		this.articleWebId = articleWebId;
+	}
+	
+	public String getArticleUrl(AppEntity app) {
+		if (!StringUtils.isBlank(app.getAppMobileStyle())) {
+			return app.getAppHostUrl()+ParserUtil.HTML+Const.SEPARATOR+ParserUtil.MOBILE+Const.SEPARATOR+this.getArticleUrl();
+		}
+		return app.getAppHostUrl()+Const.SEPARATOR+ParserUtil.HTML+Const.SEPARATOR+this.getArticleUrl();
+	}
+}

+ 3 - 0
src/main/java/net/mingsoft/cms/resources/resources_zh_CN.properties

@@ -0,0 +1,3 @@
+#mcms\u7248\u672c
+version=d3a98fefcb242db78da5fc31608ff247
+templet.file=\u6a21\u677f\u6587\u4ef6\u4e0d\u5b58\u5728

+ 244 - 0
src/main/java/net/mingsoft/cms/util/CmsParserUtil.java

@@ -0,0 +1,244 @@
+package net.mingsoft.cms.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import net.mingsoft.basic.entity.ColumnEntity;
+import net.mingsoft.cms.bean.ColumnArticleIdBean;
+import net.mingsoft.cms.constant.e.ColumnTypeEnum;
+import net.mingsoft.mdiy.biz.IContentModelBiz;
+import net.mingsoft.mdiy.entity.ContentModelEntity;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.PageUtil;
+import freemarker.cache.FileTemplateLoader;
+import freemarker.core.ParseException;
+import freemarker.template.MalformedTemplateNameException;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateNotFoundException;
+import net.mingsoft.base.constant.Const;
+import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.basic.util.SpringUtil;
+import net.mingsoft.mdiy.parser.TagParser;
+import net.mingsoft.mdiy.util.ParserUtil;
+
+public class CmsParserUtil extends ParserUtil {
+
+	/**
+	 * 指定模板,指定路径进行生成静态页面,会自定识别pc与移动端
+	 * 
+	 * @param templatePath
+	 *            模板路径
+	 * @param targetPath
+	 *            生成后的路径,默认生成的html文件,所以不能带.html后缀,
+	 * @throws IOException
+	 */
+	public static void generate(String templatePath, String targetPath) throws IOException {
+		Map map = new HashMap();
+		map.put(IS_DO, false);
+		String content = CmsParserUtil.generate(templatePath, map, false);
+		
+		FileUtil.writeString(content, ParserUtil.buildHtmlPath(targetPath), Const.UTF8);
+		// 生成移动页面
+		if (ObjectUtil.isNotNull(BasicUtil.getApp().getAppMobileStyle())) {
+			// 手机端m
+			map.put(ParserUtil.MOBILE, BasicUtil.getApp().getAppMobileStyle());
+			content = CmsParserUtil.generate(templatePath, map, true);
+			FileUtil.writeString(content, ParserUtil.buildMobileHtmlPath(targetPath), Const.UTF8);
+		}
+	}
+
+	/**
+	 * 生成静态列表页
+	 * @param column
+	 * @param articleIdTotal
+	 * @throws TemplateNotFoundException
+	 * @throws MalformedTemplateNameException
+	 * @throws ParseException
+	 * @throws IOException
+	 */
+	public static void generateList(ColumnEntity column, int articleIdTotal)
+			throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
+		// 只初始化一次cfg
+		if (ftl == null) {
+			ftl = new FileTemplateLoader(new File(ParserUtil.buildTempletPath()));
+			cfg.setTemplateLoader(ftl);
+		}
+		// 移动端模板
+		Template mobileTemplate = cfg.getTemplate(
+				BasicUtil.getApp().getAppMobileStyle() + File.separator + column.getColumnListUrl(), Const.UTF8);
+		// pc端模板
+		Template template = cfg.getTemplate(File.separator + column.getColumnListUrl(), Const.UTF8);
+
+		
+		StringWriter writer = new StringWriter();
+		try {
+			// 为了分页添加column,判断栏目是否为父栏目
+			
+			template.process(null, writer);
+			String content = writer.toString();
+			//获取列表页显示的文章数量
+			int pageSize = TagParser.getPageSize(content);
+			//获取总数
+			int totalPageSize = PageUtil.totalPage(articleIdTotal, pageSize);
+		
+			
+			String columnListPath;
+			String mobilePath;
+			
+			int pageNo = 1;
+			// 遍历分页
+			for (int i = 0; i < totalPageSize; i++) {
+				Map parserParams = new HashMap();
+				parserParams.put(COLUMN, column);
+				parserParams.put(TOTAL, totalPageSize);
+				parserParams.put(RCOUNT, pageSize);
+				parserParams.put(TYPE_ID, column.getCategoryId());
+				parserParams.put(IS_DO, false);
+				if (i == 0) {
+					// 数据库中第一页是从开始0*size
+					// 首页路径index.html
+					mobilePath = ParserUtil
+							.buildMobileHtmlPath(column.getColumnPath() + File.separator + ParserUtil.INDEX);
+					columnListPath = ParserUtil
+							.buildHtmlPath(column.getColumnPath() + File.separator + ParserUtil.INDEX);
+				} else {
+					// 其他路径list-2.html
+					mobilePath = ParserUtil.buildMobileHtmlPath(
+							column.getColumnPath() + File.separator + ParserUtil.PAGE_LIST + pageNo);
+					columnListPath = ParserUtil
+							.buildHtmlPath(column.getColumnPath() + File.separator + ParserUtil.PAGE_LIST + pageNo);
+				}
+				
+				// 设置分页的起始位置
+				parserParams.put(PAGE_NO, pageNo);
+				TagParser tag = new TagParser(content,parserParams);
+
+				FileUtil.writeString(tag.rendering(), columnListPath, Const.UTF8);
+
+				// 判断是手机端生成还是pc端,防止重复生成
+				if (ObjectUtil.isNotNull(BasicUtil.getApp().getAppMobileStyle())) {
+					writer = new StringWriter();
+					mobileTemplate.process(null, writer);
+					tag = new TagParser(writer.toString(),parserParams);
+					// 将tag.getContent()写入路径
+					FileUtil.writeString(tag.rendering(), mobilePath, Const.UTF8);
+				}
+				
+				writer = new StringWriter();
+				pageNo++;
+			}
+
+		} catch (TemplateException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * 生成内容
+	 * 
+	 * @param articleIdList
+	 *            文章集合
+	 * @return
+	 * @throws IOException
+	 * @throws ParseException
+	 * @throws MalformedTemplateNameException
+	 * @throws TemplateNotFoundException
+	 */
+	public static void generateBasic(List<ColumnArticleIdBean> articleIdList)
+			throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
+
+		Map<Object, Object> contentModelMap = new HashMap<Object, Object>();
+		ContentModelEntity contentModel = null;
+		String writePath = null;
+		// 记录已经生成了文章编号
+		List<Integer> generateIds = new ArrayList<>();
+		// 生成文档
+		for (int ai = 0; ai < articleIdList.size();) {
+			// 文章编号
+			int articleId = articleIdList.get(ai).getArticleId();
+			// 文章的栏目路径
+			String articleColumnPath = articleIdList.get(ai).getColumnPath();
+			// 文章的模板路径
+			String columnUrl = articleIdList.get(ai).getColumnUrl();
+			// 文章的栏目模型编号
+			int columnContentModelId = articleIdList.get(ai).getColumnContentModelId();
+			// 文章是否已经生成了,生成了就跳过
+			if (generateIds.contains(articleId)) {
+				ai++;
+				continue;
+			}
+
+			// 判断文件是否存在,若不存在弹出返回信息
+			if (!FileUtil.exist(ParserUtil.buildTempletPath(columnUrl))) {
+				ai++;
+				continue;
+			}
+			// 将
+			generateIds.add(articleId);
+			// 组合文章路径如:html/站点id/栏目id/文章id.html
+			writePath = ParserUtil.buildHtmlPath(articleColumnPath + File.separator + articleId);
+			//如果是封面就生成index.html
+			if(articleIdList.get(ai).getColumnType() == ColumnTypeEnum.COLUMN_TYPE_COVER.toInt()) {
+				writePath = ParserUtil.buildHtmlPath(articleColumnPath + File.separator + ParserUtil.INDEX);
+			}
+			Map<String, Object> parserParams = new HashMap<String, Object>();
+			// 判断当前栏目是否有自定义模型
+			if (columnContentModelId > 0) {
+				// 通过当前栏目的模型编号获取,自定义模型表名
+				if (contentModelMap.containsKey(columnContentModelId)) {
+					parserParams.put(TABLE_NAME, contentModel.getCmTableName());
+				} else {
+					// 通过栏目模型编号获取自定义模型实体
+					contentModel = (ContentModelEntity) SpringUtil.getBean(IContentModelBiz.class)
+							.getEntity(columnContentModelId);
+					// 将自定义模型编号设置为key值
+					contentModelMap.put(columnContentModelId, contentModel.getCmTableName());
+					parserParams.put(TABLE_NAME, contentModel.getCmTableName());
+				}
+			}
+
+			parserParams.put(ID, articleId);
+			// 第一篇文章没有上一篇
+			if (ai > 0) {
+				parserParams.put(PRE_ID, articleIdList.get(ai - 1).getArticleId());
+			}
+			// 最后一篇文章没有下一篇
+			if (ai + 1 < articleIdList.size()) {
+				parserParams.put(NEXT_ID, articleIdList.get(ai + 1).getArticleId());
+			}
+
+			parserParams.put(IS_DO, false);
+			
+			String content = CmsParserUtil.generate(articleIdList.get(ai).getColumnUrl(), parserParams, false);
+			FileUtil.writeString(content, writePath, Const.UTF8);
+
+			// 手机端
+			if (StringUtils.isNotEmpty(BasicUtil.getApp().getAppMobileStyle())) {
+				writePath = ParserUtil.buildMobileHtmlPath(articleColumnPath + File.separator + articleId);
+				//如果是封面就生成index.html
+				if(articleIdList.get(ai).getColumnType() == ColumnTypeEnum.COLUMN_TYPE_COVER.toInt()) {
+					writePath = ParserUtil.buildMobileHtmlPath(articleColumnPath + File.separator + ParserUtil.INDEX);
+				}
+				// 判断文件是否存在,若不存在弹出返回信息
+				if (!FileUtil.exist(ParserUtil.buildTempletPath(MOBILE + File.separator + columnUrl))) {
+					ai++;
+					continue;
+				}
+				parserParams.put(MOBILE, BasicUtil.getApp().getAppMobileStyle());
+				content = CmsParserUtil.generate(articleIdList.get(ai).getColumnUrl(), parserParams, true);
+				FileUtil.writeString(content, writePath, Const.UTF8);
+			}
+			ai++;
+		}
+	}
+}