Explorar el Código

5.2.9 预发布版本

zhouyk hace 3 años
padre
commit
eebc37811e

+ 1 - 0
README.md

@@ -143,6 +143,7 @@ git clone https://gitee.com/mingSoft/MCMS.git<br/>
 
 # 文档
 * 使用手册 http://doc.mingsoft.net/mcms/
+* 插件手册 http://doc.mingsoft.net/plugs-cms/
 
 # 关于版本说明 [更多版本查看](https://www.mingsoft.net/html/default/cms/banben/index.html)
 1. 开源版本永久免费发布源代码,开发者、企业可以终身免费使用,每个月团队会收集开源系统的问题并在每月的28号进行更新;

+ 11 - 7
pom.xml

@@ -10,14 +10,14 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>net.mingsoft</groupId>
     <artifactId>ms-mcms</artifactId>
-    <version>5.2.8</version>
+    <version>5.2.9</version>
     <name>${project.groupId}:${project.artifactId}</name>
     <!-- 打包war包,注意不启用(resources》resource》excludes的配置并注释掉maven-assembly-plugin 插件配置 -->
     <!--<packaging>war</packaging>-->
     <properties>
         <java.version>1.8</java.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <log4j.version>2.17.0</log4j.version>
+        <log4j.version>2.18.0</log4j.version>
     </properties>
     <repositories>
         <repository>
@@ -44,26 +44,30 @@
         <dependency>
             <groupId>net.mingsoft</groupId>
             <artifactId>ms-base</artifactId>
-            <version>2.1.13</version>
+            <version>2.1.14</version>
         </dependency>
         <dependency>
             <groupId>net.mingsoft</groupId>
             <artifactId>ms-basic</artifactId>
-            <version>2.1.13.4</version>
+            <version>2.1.14</version>
         </dependency>
         <dependency>
             <groupId>net.mingsoft</groupId>
             <artifactId>ms-mdiy</artifactId>
-            <version>2.1.13.1</version>
+            <version>2.1.14</version>
         </dependency>
 
         <!--store入口依赖(源码不开发),如果不需要MStore可以直接去掉依赖-->
         <dependency>
             <groupId>net.mingsoft</groupId>
             <artifactId>store-client</artifactId>
-            <version>2.1.13</version>
+            <version>2.1.14</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.oshi</groupId>
+            <artifactId>oshi-core</artifactId>
+            <version>6.2.2</version>
         </dependency>
-
         <dependency>
             <groupId>org.apache.logging.log4j</groupId>
             <artifactId>log4j-core</artifactId>

+ 0 - 1
src/main/java/net/mingsoft/MSApplication.java

@@ -32,7 +32,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
 import java.util.Locale;
 
-
 @SpringBootApplication(scanBasePackages = {"net.mingsoft"})
 @MapperScan(basePackages={"**.dao","com.baomidou.**.mapper"})
 @ServletComponentScan(basePackages = {"net.mingsoft"})

+ 9 - 1
src/main/java/net/mingsoft/cms/action/CategoryAction.java

@@ -151,6 +151,10 @@ public class CategoryAction extends BaseAction {
 	@LogAnn(title = "保存分类", businessType = BusinessTypeEnum.INSERT)
 	@RequiresPermissions("cms:category:save")
 	public ResultData save(@ModelAttribute @ApiIgnore CategoryEntity category) {
+		//验证缩略图参数值是否合法
+		if (!category.getCategoryImg().matches("^\\[.{1,}]$") || category.getCategoryImg()==null){
+			category.setCategoryImg("");
+		}
 		//验证栏目管理名称的值是否合法
 		if(StringUtil.isBlank(category.getCategoryTitle())){
 			return ResultData.build().error(getResString("err.empty", this.getResString("category.title")));
@@ -229,6 +233,10 @@ public class CategoryAction extends BaseAction {
 	@LogAnn(title = "更新分类", businessType = BusinessTypeEnum.UPDATE)
 	@RequiresPermissions("cms:category:update")
 	public ResultData update(@ModelAttribute @ApiIgnore CategoryEntity category) {
+		 //验证缩略图参数值是否合法
+		 if (!category.getCategoryImg().matches("^\\[.{1,}]$") || category.getCategoryImg()==null){
+			 category.setCategoryImg("");
+		 }
 		//验证栏目管理名称的值是否合法
 		if(StringUtil.isBlank(category.getCategoryTitle())){
 			return ResultData.build().error(getResString("err.empty", this.getResString("category.title")));
@@ -298,7 +306,7 @@ public class CategoryAction extends BaseAction {
 	@GetMapping("/verifyPingYin")
 	@ResponseBody
 	public ResultData verifyPingYin(@ModelAttribute @ApiIgnore CategoryEntity category){
-	 	int count = categoryBiz.count(Wrappers.<CategoryEntity>lambdaQuery()
+	 	long count = categoryBiz.count(Wrappers.<CategoryEntity>lambdaQuery()
 				.ne(StrUtil.isNotBlank(category.getId()), CategoryEntity::getId, category.getId())
 				.eq(CategoryEntity::getCategoryPinyin, category.getCategoryPinyin()));
 

+ 14 - 3
src/main/java/net/mingsoft/cms/action/ContentAction.java

@@ -31,7 +31,7 @@ import net.mingsoft.basic.annotation.LogAnn;
 import net.mingsoft.basic.bean.EUListBean;
 import net.mingsoft.basic.constant.e.BusinessTypeEnum;
 import net.mingsoft.basic.util.BasicUtil;
-import net.mingsoft.basic.util.SqlInjectionUtil;
+import net.mingsoft.base.util.SqlInjectionUtil;
 import net.mingsoft.basic.util.StringUtil;
 import net.mingsoft.cms.bean.ContentBean;
 import net.mingsoft.cms.biz.ICategoryBiz;
@@ -40,6 +40,7 @@ import net.mingsoft.cms.entity.CategoryEntity;
 import net.mingsoft.cms.entity.ContentEntity;
 import net.mingsoft.mdiy.biz.IModelBiz;
 import net.mingsoft.mdiy.entity.ModelEntity;
+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;
@@ -85,6 +86,7 @@ public class ContentAction extends BaseAction {
 	/**
 	 * 返回主界面index
 	 */
+	@ApiIgnore
 	@GetMapping("/index")
 	public String index(){
 		return "/cms/content/index";
@@ -93,6 +95,7 @@ public class ContentAction extends BaseAction {
 	/**
 	 * 返回主界面main
 	 */
+	@ApiIgnore
 	@GetMapping("/main")
 	public String main(){
 		return "/cms/content/main";
@@ -119,7 +122,7 @@ public class ContentAction extends BaseAction {
 		// 检查SQL注入
 		SqlInjectionUtil.filterContent(content.getCategoryId());
 		BasicUtil.startPage();
-		List contentList = contentBiz.query(content);
+		List contentList = contentBiz.queryContent(content);
 		return ResultData.build().success(new EUListBean(contentList,(int) BasicUtil.endPage(contentList).getTotal()));
 	}
 
@@ -195,6 +198,10 @@ public class ContentAction extends BaseAction {
 	@LogAnn(title = "保存文章", businessType = BusinessTypeEnum.INSERT)
 	@RequiresPermissions("cms:content:save")
 	public ResultData save(@ModelAttribute @ApiIgnore ContentEntity content) {
+		//验证缩略图参数值是否合法
+		if (content.getContentImg()==null || !content.getContentImg().matches("^\\[.{1,}]$")){
+			content.setContentImg("");
+		}
 		//验证文章标题的值是否合法
 		if(StringUtil.isBlank(content.getContentTitle())){
 			return ResultData.build().error(getResString("err.empty", this.getResString("content.title")));
@@ -238,7 +245,7 @@ public class ContentAction extends BaseAction {
 			//获取栏目实体
 			CategoryEntity categoryEntity = categoryBiz.getById(contents.get(i).getCategoryId());
 			//如果栏目绑定的模型ID为空
-			if (categoryEntity.getMdiyModelId() == null){
+			if (StringUtils.isBlank(categoryEntity.getMdiyModelId())){
 				continue;
 			}
 			//获取到配置模型实体
@@ -279,6 +286,10 @@ public class ContentAction extends BaseAction {
 	@LogAnn(title = "更新文章", businessType = BusinessTypeEnum.UPDATE)
 	@RequiresPermissions("cms:content:update")
 	public ResultData update(@ModelAttribute @ApiIgnore ContentEntity content) {
+		 //验证缩略图参数值是否合法
+		 if (content.getContentImg()==null || !content.getContentImg().matches("^\\[.{1,}]$")){
+			 content.setContentImg("");
+		 }
 		//验证文章标题的值是否合法
 		if(StringUtil.isBlank(content.getContentTitle())){
 			return ResultData.build().error(getResString("err.empty", this.getResString("content.title")));

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

@@ -99,7 +99,7 @@ public class GeneraterAction extends BaseAction {
     @Value("${ms.manager.path}")
     private String managerPath;
 
-    @Value("${ms.html-dir:html}")
+    @Value("${ms.diy.html-dir:html}")
     private String htmlDir;
 
     /**
@@ -251,7 +251,7 @@ public class GeneraterAction extends BaseAction {
             contentBean.setCategoryId(category.getId());
             contentBean.setCategoryType(category.getCategoryType());
             //将文章列表标签中的中的参数
-            articleIdList = contentBiz.queryIdsByCategoryIdForParser(contentBean);
+            articleIdList = contentBiz.queryIdsByCategoryIdForParserAndNotCover(contentBean);
             // 分类是列表
             if (category.getCategoryType().equals(CategoryTypeEnum.LIST.toString())) {
                 // 判断模板文件是否存在

+ 4 - 21
src/main/java/net/mingsoft/cms/action/web/MCmsAction.java

@@ -19,9 +19,6 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-
-
-
 package net.mingsoft.cms.action.web;
 
 import cn.hutool.core.util.ObjectUtil;
@@ -31,24 +28,19 @@ import freemarker.core.ParseException;
 import freemarker.template.MalformedTemplateNameException;
 import freemarker.template.TemplateNotFoundException;
 import net.mingsoft.base.constant.Const;
-import net.mingsoft.basic.exception.BusinessException;
 import net.mingsoft.basic.util.BasicUtil;
-import net.mingsoft.cms.bean.CategoryBean;
-import net.mingsoft.cms.bean.ContentBean;
 import net.mingsoft.cms.biz.ICategoryBiz;
 import net.mingsoft.cms.biz.IContentBiz;
 import net.mingsoft.cms.entity.CategoryEntity;
-import net.mingsoft.cms.entity.ContentEntity;
 import net.mingsoft.mdiy.bean.PageBean;
 import net.mingsoft.mdiy.biz.IModelBiz;
-import net.mingsoft.mdiy.biz.IPageBiz;
 import net.mingsoft.mdiy.entity.ModelEntity;
 import net.mingsoft.mdiy.util.ParserUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.MediaType;
 import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseBody;
@@ -76,12 +68,6 @@ import java.util.Map;
 public class MCmsAction extends net.mingsoft.cms.action.BaseAction {
 
     /**
-     * 自定义页面业务层
-     */
-    @Autowired
-    private IPageBiz pageBiz;
-
-    /**
      * 文章管理业务处理层
      */
     @Autowired
@@ -101,19 +87,16 @@ public class MCmsAction extends net.mingsoft.cms.action.BaseAction {
     private IModelBiz modelBiz;
 
 
-    @Value("${ms.html-dir:html}")
+    @Value("${ms.diy.html-dir:html}")
     private String htmlDir;
 
-
-   
-
     /**
      * 实现前端页面的文章搜索
      *
      * @param request  搜索id
      * @param response
      */
-    @RequestMapping(value = "search",method = {RequestMethod.GET, RequestMethod.POST})
+    @RequestMapping(value = "search",method = {RequestMethod.GET, RequestMethod.POST},produces= MediaType.TEXT_HTML_VALUE+";charset=utf-8")
     @ResponseBody
     public String search(HttpServletRequest request, HttpServletResponse response) {
         String search = BasicUtil.getString("tmpl", "search.htm");
@@ -178,7 +161,7 @@ public class MCmsAction extends net.mingsoft.cms.action.BaseAction {
             column = (CategoryEntity) categoryBiz.getById(typeId);
             // 获取表单类型的id
             if (column != null && ObjectUtil.isNotNull(column.getMdiyModelId())) {
-                contentModel = (ModelEntity) modelBiz.getEntity(column.getMdiyModelId());
+                contentModel = (ModelEntity) modelBiz.getById(column.getMdiyModelId());
                 if (contentModel != null) {
                     // 保存自定义模型的数据
                     Map<String, String> fieldMap = contentModel.getFieldMap();

+ 73 - 4
src/main/java/net/mingsoft/cms/aop/CategoryAop.java

@@ -7,14 +7,22 @@
 package net.mingsoft.cms.aop;
 
 import cn.hutool.core.io.FileUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import net.mingsoft.base.entity.ResultData;
+import net.mingsoft.basic.exception.BusinessException;
 import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.cms.constant.e.CategoryTypeEnum;
+import net.mingsoft.cms.dao.ICategoryDao;
+import net.mingsoft.cms.dao.IContentDao;
 import net.mingsoft.cms.entity.CategoryEntity;
-import net.mingsoft.mdiy.biz.IDictBiz;
-import net.mingsoft.mdiy.entity.DictEntity;
+import net.mingsoft.cms.entity.ContentEntity;
 import org.apache.commons.lang3.StringUtils;
 import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Pointcut;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -23,7 +31,6 @@ import org.springframework.stereotype.Component;
 
 import java.io.File;
 import java.util.List;
-import java.util.stream.Collectors;
 
 
 /**
@@ -38,12 +45,74 @@ public class CategoryAop extends net.mingsoft.basic.aop.BaseAop {
     @Value("${ms.diy.html-dir:html}")
     private String htmlDir;
 
+    @Autowired
+    private ICategoryDao categoryDao;
+
+    @Autowired
+    private IContentDao contentDao;
 
     @Pointcut("execution(* net.mingsoft.cms.action.CategoryAction.delete(..)) ")
     public void delete() {
     }
 
     /**
+     * 栏目保存接口切面
+     */
+    @Pointcut("execution(* net.mingsoft.cms.action.CategoryAction.save(..)) ")
+    public void save() {}
+
+    /**
+     * 栏目更新接口切面
+     */
+    @Pointcut("execution(* net.mingsoft.cms.action.CategoryAction.update(..)) ")
+    public void update() {}
+
+
+
+    @Around("save() || update()")
+    public ResultData move(ProceedingJoinPoint pjp) throws Throwable {
+        CategoryEntity category = getType(pjp, CategoryEntity.class);
+        if (category == null) {
+            throw new BusinessException("栏目不存在!");
+        }
+
+        // 获取返回值
+        Object obj = pjp.proceed(pjp.getArgs());
+        ResultData resultData = JSONObject.parseObject(JSONObject.toJSON(obj).toString(), ResultData.class);
+        CategoryEntity parent = categoryDao.selectById(category.getCategoryId());
+        if (parent == null) {
+            return resultData;
+        }
+        // 用于判断父级栏目之前是否是子栏目
+        // 只有父节点之前为子节点 && 父栏目类型为列表 && 子栏目为列表
+        boolean flag = parent.getLeaf() && StringUtils.equals(parent.getCategoryType(), CategoryTypeEnum.LIST.toString());
+        if (flag) {
+            // 将父栏目的内容模板清空
+            parent.setCategoryUrl("");
+            categoryDao.updateById(parent);
+            CategoryEntity returnCategory = JSONObject.parseObject(resultData.get(ResultData.DATA_KEY).toString(), CategoryEntity.class);
+            // 获取父栏目ID集合
+            String categoryIds = StringUtils.isEmpty(parent.getCategoryParentIds())
+                    ? returnCategory.getId() : parent.getCategoryParentIds() + "," + returnCategory.getId();
+            if (!StringUtils.equals(returnCategory.getCategoryType(), CategoryTypeEnum.LIST.toString())) {
+                // 如果子栏目不为列表,将直接删除父栏目下的文章
+                LambdaUpdateWrapper<ContentEntity> contentDeleteWrapper = new UpdateWrapper<ContentEntity>().lambda();
+                contentDeleteWrapper.eq(ContentEntity::getCategoryId, parent.getId());
+                contentDao.delete(contentDeleteWrapper);
+            }
+            // 将父栏目下的文章移动到子栏目下
+            LambdaUpdateWrapper<ContentEntity> contentWrapper = new UpdateWrapper<ContentEntity>().lambda();
+            contentWrapper.set(ContentEntity::getCategoryId, returnCategory.getId());
+            contentWrapper.eq(ContentEntity::getCategoryId, parent.getId());
+            contentDao.update(new ContentEntity(), contentWrapper);
+
+            return resultData;
+        }
+        return resultData;
+    }
+
+
+    /**
      * 删除栏目后并删除文章对应的静态化文件
      *
      * @param jp

+ 20 - 0
src/main/java/net/mingsoft/cms/biz/IContentBiz.java

@@ -40,12 +40,32 @@ import java.util.Map;
  */
 public interface IContentBiz extends IBaseBiz<ContentEntity> {
 
+
     /**
      * 根据文章属性查询
      * @param contentBean
      * @return
      */
     List<CategoryBean> queryIdsByCategoryIdForParser(ContentBean contentBean);
+    /**
+     * 查询文章,不包括单篇
+     * @param contentBean
+     * @return
+     */
+    List<CategoryBean> queryContent(ContentBean contentBean);
 
     int getSearchCount(ModelEntity contentModel, List diyList, Map whereMap, int appId, String categoryIds);
+    /**
+     * 根据文章属性查询,不包括单篇
+     * @param contentBean
+     * @return
+     */
+    List<CategoryBean> queryIdsByCategoryIdForParserAndNotCover(ContentBean contentBean);
+
+    /**
+     * 根据解析标签arclist的sql获取list
+     * @return
+     */
+    List list(Map map);
+
 }

+ 40 - 3
src/main/java/net/mingsoft/cms/biz/impl/ContentBizImpl.java

@@ -24,6 +24,8 @@
 
 package net.mingsoft.cms.biz.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import freemarker.template.TemplateException;
 import net.mingsoft.base.biz.impl.BaseBizImpl;
 import net.mingsoft.base.dao.IBaseDao;
 import net.mingsoft.cms.bean.CategoryBean;
@@ -32,13 +34,16 @@ import net.mingsoft.cms.biz.IContentBiz;
 import net.mingsoft.cms.dao.ICategoryDao;
 import net.mingsoft.cms.dao.IContentDao;
 import net.mingsoft.cms.entity.ContentEntity;
+import net.mingsoft.mdiy.biz.ITagBiz;
 import net.mingsoft.mdiy.entity.ModelEntity;
+import net.mingsoft.mdiy.entity.TagEntity;
+import net.mingsoft.mdiy.util.ParserUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 
@@ -64,9 +69,9 @@ public class ContentBizImpl  extends BaseBizImpl<IContentDao, ContentEntity> imp
 	@Autowired
 	private ICategoryDao categoryDao;
 
-	@Value("${ms.html-dir:html}")
-	private String htmlDir;
 
+	@Autowired
+	private ITagBiz tagBiz;
 
 	@Override
 	protected IBaseDao getDao() {
@@ -74,12 +79,19 @@ public class ContentBizImpl  extends BaseBizImpl<IContentDao, ContentEntity> imp
 		return contentDao;
 	}
 
+
 	@Override
 	public List<CategoryBean> queryIdsByCategoryIdForParser(ContentBean contentBean) {
 		return this.contentDao.queryIdsByCategoryIdForParser(contentBean);
 	}
 
 	@Override
+	public List<CategoryBean> queryContent(ContentBean contentBean) {
+		return this.contentDao.queryContent(contentBean);
+
+	}
+
+	@Override
 	public int getSearchCount(ModelEntity contentModel, List diyList, Map whereMap, int appId, String categoryIds) {
 		if (contentModel!=null) {
 			return contentDao.getSearchCount(contentModel.getModelTableName(),diyList,whereMap, appId,categoryIds);
@@ -87,5 +99,30 @@ public class ContentBizImpl  extends BaseBizImpl<IContentDao, ContentEntity> imp
 		return contentDao.getSearchCount(null,null,whereMap, appId,categoryIds);
 	}
 
+	@Override
+	public List<CategoryBean> queryIdsByCategoryIdForParserAndNotCover(ContentBean contentBean) {
+		return this.contentDao.queryIdsByCategoryIdForParser(contentBean);
+	}
+
+	@Override
+	public List list(Map map ) {
+		//通过tagSqlBiz获取arclist对应的sql
+		QueryWrapper<TagEntity> tagWrapper = new QueryWrapper<>();
+		tagWrapper.eq("tag_name", "arclist");
+		TagEntity tagEntity = tagBiz.getOne(tagWrapper);
+		String sqlFtl = tagEntity.getTagSql();
+		List<ContentEntity> contentEntities = null;
+		//通过ParserUtil
+		try {
+			String sql = ParserUtil.rendering(map,sqlFtl);
+			//执行原生的sql
+			contentEntities = (List<ContentEntity>) tagBiz.excuteSql(sql);
+		} catch (IOException e) {
+			e.printStackTrace();
+		} catch (TemplateException e) {
+			e.printStackTrace();
+		}
+		return contentEntities;
+	}
 
 }

+ 7 - 2
src/main/java/net/mingsoft/cms/constant/e/CategoryTypeEnum.java

@@ -43,7 +43,12 @@ public enum CategoryTypeEnum implements BaseEnum {
     /**
      * 链接
      */
-    LINK("3");
+    LINK("3"),
+
+    /**
+     * 未知类型
+     */
+    UN_KNOW("0");
 
 
     CategoryTypeEnum(String type) {
@@ -58,7 +63,7 @@ public enum CategoryTypeEnum implements BaseEnum {
                 return e;
             }
         }
-        return null;
+        return CategoryTypeEnum.UN_KNOW;
     }
 
     @Override

+ 9 - 7
src/main/java/net/mingsoft/cms/dao/ICategoryDao.xml

@@ -40,6 +40,7 @@
 				<if test="leaf != null">leaf=#{leaf},</if>
 				category_id=#{categoryId},
 				category_parent_ids=#{categoryParentIds},
+				mdiy_model_id=#{mdiyModelId},
 				<if test="categoryType != null and categoryType != ''">category_type=#{categoryType},</if>
 				<if test="categorySort != null">category_sort=#{categorySort},</if>
 				category_list_url=#{categoryListUrl},
@@ -48,7 +49,6 @@
 				<if test="categoryDescrip != null ">category_descrip=#{categoryDescrip},</if>
 				<if test="categoryImg != null and categoryImg != ''">category_img=#{categoryImg},</if>
 				<if test="categoryDiyUrl != null">category_diy_url=#{categoryDiyUrl},</if>
-				<if test="mdiyModelId != null and mdiyModelId != ''">mdiy_model_id=#{mdiyModelId},</if>
 				<if test="dictId != null">dict_id=#{dictId},</if>
 				<if test="categoryFlag != null ">category_flag=#{categoryFlag},</if>
 				<if test="categoryPath != null and categoryPath != ''">category_path=#{categoryPath},</if>
@@ -98,18 +98,20 @@
 
 	<!-- 模糊查询开始 -->
 	<select id="queryChildren" resultMap="resultMap">
-		select * from cms_category
+		select *,
+		( SELECT count(*) FROM cms_category cc WHERE cc.category_id = cms_category.id AND cc.del = 0 ) AS childsize from cms_category
 		<where>
-
+			del=0
 			<if test="dictId &gt; 0">
 				and dict_id=#{dictId}
 			</if>
-			and
-			(
+			<if test="id != null and id != ''">
+				and
+				(
 				find_in_set(#{id},CATEGORY_PARENT_IDS)>0
 				or id=#{id}
-			)
-			and del=0
+				)
+			</if>
 		</where>
 	</select>
 

+ 16 - 0
src/main/java/net/mingsoft/cms/dao/IContentDao.java

@@ -39,6 +39,8 @@ import java.util.Map;
  */
 public interface IContentDao extends IBaseDao<ContentEntity> {
 
+
+
     /**
      * 查询文章编号集合
      * @contentBean
@@ -47,6 +49,20 @@ public interface IContentDao extends IBaseDao<ContentEntity> {
     public List<CategoryBean> queryIdsByCategoryIdForParser(ContentBean contentBean);
 
     /**
+     * 查询文章编号集合,不包括单篇
+     * @contentBean
+     * @return
+     */
+    public List<CategoryBean> queryIdsByCategoryIdForParserAndNotCover(ContentBean contentBean);
+
+    /**
+     * 查询文章,不包括单篇
+     * @contentBean
+     * @return
+     */
+    public List<CategoryBean> queryContent(ContentBean contentBean);
+
+    /**
      * 根据查询文章实体总数
      *
      * @param tableName

+ 99 - 1
src/main/java/net/mingsoft/cms/dao/IContentDao.xml

@@ -207,6 +207,45 @@
 		<select id="queryAll" resultMap="resultMap">
 			select * from cms_content where del=0 order by id desc
 		</select>
+
+
+	<!--  查询文章,不包括单篇	-->
+	<select id="queryContent" resultMap="resultContentMap">
+		<!--,CONCAT('/html/',ct.app_id,category_path,'/',ct.id,'.html') AS static_url-->
+		select ct.* from (
+		select ct.*,cc.category_path from cms_content ct
+		join cms_category cc on ct.category_id=cc.id
+		<where>
+			ct.del=0
+			<if test="contentTitle != null and contentTitle != ''"> and  content_title like CONCAT(CONCAT('%',#{contentTitle}),'%')</if>
+			<if test="categoryId != null and categoryId != ''"> 	and (ct.category_id=#{categoryId} or ct.category_id in
+				(select id FROM cms_category where find_in_set(#{categoryId},CATEGORY_PARENT_IDS)>0 and cms_category.category_type != 2))</if>
+			<if test="contentType != null and contentType != ''">
+				and
+				<foreach item="item" index="index" collection="contentType.split(',')" open="(" separator="or"
+						 close=")">
+					FIND_IN_SET(#{item},ct.content_type)>0
+				</foreach>
+			</if>
+			<if test="contentDisplay != null and contentDisplay != ''"> and content_display=#{contentDisplay}</if>
+			<if test="contentAuthor != null and contentAuthor != ''"> and content_author=#{contentAuthor}</if>
+			<if test="contentSource != null and contentSource != ''"> and content_source=#{contentSource}</if>
+			<if test="contentDatetime != null"> and content_datetime=#{contentDatetime} </if>
+			<if test="contentSort != null"> and content_sort=#{contentSort} </if>
+			<if test="contentImg != null and contentImg != ''"> and content_img=#{contentImg}</if>
+			<if test="contentDescription != null and contentDescription != ''"> and content_description=#{contentDescription}</if>
+			<if test="contentKeyword != null and contentKeyword != ''"> and content_keyword=#{contentKeyword}</if>
+			<if test="contentDetails != null and contentDetails != ''"> and content_details=#{contentDetails}</if>
+			<if test="contentUrl != null and contentUrl != ''"> and content_url=#{contentUrl}</if>
+			<if test="contentHit != null"> and content_hit=#{contentHit}</if>
+			<if test="createBy &gt; 0"> and ct.create_by=#{createBy} </if>
+			<if test="createDate != null"> and ct.create_date=#{createDate} </if>
+			<if test="updateBy &gt; 0"> and ct.update_by=#{updateBy} </if>
+			<if test="updateDate != null"> and update_date=#{updateDate} </if>
+			<include refid="net.mingsoft.base.dao.IBaseDao.sqlWhere"></include>
+		</where>
+		)ct ORDER BY ct.content_datetime desc,content_sort desc
+	</select>
 	<!--条件查询-->
 	<select id="query" resultMap="resultContentMap">
 		<!--,CONCAT('/html/',ct.app_id,category_path,'/',ct.id,'.html') AS static_url-->
@@ -288,7 +327,7 @@
 				<if test="orderBy=='hit'">ORDER BY content_hit</if>
 				<if test="orderBy=='sort'">ORDER BY content_sort</if>
 				<if  test="orderBy!='date' and orderBy!='hit' and orderBy!='sort'">
-					ORDER BY ct.id
+					ORDER BY ct.content_datetime
 				</if>
 				<choose>
 					<when test="order!=null and order!=''">
@@ -301,6 +340,65 @@
 			</if>
 
 	</select>
+
+
+	<!-- 根据站点编号、开始、结束时间和栏目编号查询文章编号集合,不包括单篇 -->
+	<select id="queryIdsByCategoryIdForParserAndNotCover" resultMap="resultBean" >
+		select
+		ct.id article_id,c.*
+		FROM cms_content ct
+		LEFT JOIN cms_category c ON ct.category_id = c.id
+		where ct.del=0
+
+		<!-- 查询子栏目数据 -->
+		<if test="categoryId!=null and  categoryId!='' and categoryType==1">
+			and (ct.category_id=#{categoryId} or ct.category_id in
+			(select id FROM cms_category where find_in_set(#{categoryId},CATEGORY_PARENT_IDS)>0 and category_type!=2))
+		</if>
+		<if test="categoryId!=null and  categoryId!='' and categoryType==2">
+			and ct.category_id=#{categoryId}
+		</if>
+		<if test="beginTime!=null and beginTime!=''">
+			<if test="_databaseId == 'mysql'">
+				AND ct.UPDATE_DATE &gt;=  #{beginTime}
+			</if>
+			<if test="_databaseId == 'oracle'">
+				and ct.UPDATE_DATE &gt;= to_date(#{beginTime}, 'yyyy-mm-dd hh24:mi:ss')
+			</if>
+		</if>
+		<if test="endTime!=null and endTime!=''">
+			<if test="_databaseId == 'mysql'">
+				and ct.UPDATE_DATE &gt;= #{endTime}
+			</if>
+			<if test="_databaseId == 'oracle'">
+				and ct.UPDATE_DATE &gt;= to_date(#{endTime}, 'yyyy-mm-dd hh24:mi:ss')
+			</if>
+		</if>
+		<if test="flag!=null and flag!=''">
+			and ct.content_type in ( #{flag})
+		</if>
+		<if  test="noflag!=null and noflag!=''">
+			and (ct.content_type not in ( #{noflag}  ) or ct.content_type is null)
+		</if>
+		<if test="orderBy!=null  and orderBy!='' ">
+			<if test="orderBy=='date'">ORDER BY content_datetime</if>
+			<if test="orderBy=='hit'">ORDER BY content_hit</if>
+			<if test="orderBy=='sort'">ORDER BY content_sort</if>
+			<if  test="orderBy!='date' and orderBy!='hit' and orderBy!='sort'">
+				ORDER BY ct.content_datetime
+			</if>
+			<choose>
+				<when test="order!=null and order!=''">
+					${order}
+				</when>
+				<otherwise>
+					desc
+				</otherwise>
+			</choose>
+		</if>
+
+	</select>
+
 	<select id="getSearchCount" resultType="int">
 		select count(*) from
 		cms_content a

+ 33 - 9
src/main/java/net/mingsoft/cms/entity/CategoryEntity.java

@@ -22,13 +22,12 @@
 
 package net.mingsoft.cms.entity;
 
-import com.alibaba.fastjson.annotation.JSONField;
-import com.baomidou.mybatisplus.annotation.*;
-import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import net.mingsoft.base.entity.BaseEntity;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.util.Date;
 
 /**
  * 分类实体
@@ -106,7 +105,7 @@ public class CategoryEntity extends BaseEntity {
     /**
      * 栏目管理的内容模型id
      */
-    private Integer mdiyModelId;
+    private String mdiyModelId;
 
     /**
      * 字典对应编号
@@ -123,6 +122,7 @@ public class CategoryEntity extends BaseEntity {
     /**
      * 父类型编号
      */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
     private String categoryParentIds;
 
     /**
@@ -299,11 +299,11 @@ public class CategoryEntity extends BaseEntity {
         return this.categoryDiyUrl;
     }
 
-    public Integer getMdiyModelId() {
+    public String getMdiyModelId() {
         return mdiyModelId;
     }
 
-    public void setMdiyModelId(Integer mdiyModelId) {
+    public void setMdiyModelId(String mdiyModelId) {
         this.mdiyModelId = mdiyModelId;
     }
 
@@ -442,4 +442,28 @@ public class CategoryEntity extends BaseEntity {
         return categoryPath;
     }
 
+    /**
+     * 获取栏目属性 (标签使用)
+     */
+    @TableField(exist = false)
+    private String type;
+
+    public String getType() {
+        return this.categoryType;
+    }
+
+    /**
+     * 获取子分类数量 (标签使用)
+     */
+    @TableField(exist = false)
+    private String childsize;
+
+    public String getChildsize() {
+        return this.childsize;
+    }
+
+    public void setChildsize(String childsize) {
+        this.childsize = childsize;
+    }
+
 }

+ 11 - 8
src/main/java/net/mingsoft/cms/util/CmsParserUtil.java

@@ -24,6 +24,7 @@ package net.mingsoft.cms.util;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.PageUtil;
 import freemarker.core.ParseException;
 import freemarker.template.MalformedTemplateNameException;
@@ -138,7 +139,7 @@ public class CmsParserUtil {
             // 判断当前栏目是否有自定义模型
             if (column.getMdiyModelId() != null) {
                 // 通过栏目模型编号获取自定义模型实体
-                contentModel = (ModelEntity) SpringUtil.getBean(ModelBizImpl.class).getEntity(column.getMdiyModelId());
+                contentModel = (ModelEntity) SpringUtil.getBean(ModelBizImpl.class).getById(column.getMdiyModelId());
             }
 
             if (contentModel != null) {
@@ -232,8 +233,8 @@ public class CmsParserUtil {
             String columnUrl = categoryBean.getCategoryUrl();
             LOG.debug("columnUrl {}",columnUrl);
             // 文章的栏目模型编号
-            Integer columnContentModelId = null;
-            if (articleIdList.get(artId).getMdiyModelId() != null && categoryBean.getMdiyModelId() > 0) {
+            String columnContentModelId = null;
+            if (StringUtils.isNotBlank(articleIdList.get(artId).getMdiyModelId()) && StringUtils.isNotBlank(categoryBean.getMdiyModelId())) {
                 columnContentModelId = categoryBean.getMdiyModelId();
             }
 
@@ -270,10 +271,12 @@ public class CmsParserUtil {
                 } else {
                     // 通过栏目模型编号获取自定义模型实体
                     contentModel = (ModelEntity) SpringUtil.getBean(IModelBiz.class)
-                            .getEntity(columnContentModelId);
-                    // 将自定义模型编号设置为key值
-                    contentModelMap.put(columnContentModelId, contentModel.getModelTableName());
-                    parserParams.put(ParserUtil.TABLE_NAME, contentModel.getModelTableName());
+                            .getById(columnContentModelId);
+                    if (null!=contentModel){
+                        // 将自定义模型编号设置为key值
+                        contentModelMap.put(columnContentModelId, contentModel.getModelTableName());
+                        parserParams.put(ParserUtil.TABLE_NAME, contentModel.getModelTableName());
+                    }
                 }
             }
 
@@ -298,7 +301,7 @@ public class CmsParserUtil {
 
             parserParams.put(ParserUtil.PAGE, page);
             String finalWritePath = writePath;
-            HashMap<Object, Object> cloneMap = CollUtil.newHashMap();
+            HashMap<Object, Object> cloneMap = MapUtil.newHashMap();
             cloneMap.putAll(parserParams);
             HttpServletRequest request = SpringUtil.getRequest();
             String content = null;

+ 13 - 16
src/main/java/net/mingsoft/config/WebConfig.java

@@ -26,14 +26,11 @@ import com.alibaba.druid.pool.DruidDataSource;
 import com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import net.mingsoft.basic.filter.XSSEscapeFilter;
 import net.mingsoft.basic.interceptor.ActionInterceptor;
 import net.mingsoft.mdiy.biz.IConfigBiz;
 import net.mingsoft.mdiy.entity.ConfigEntity;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
@@ -43,11 +40,9 @@ import org.springframework.core.Ordered;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
 import org.springframework.web.context.request.RequestContextListener;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.config.annotation.*;
 
+import javax.annotation.Resource;
 import java.io.File;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -61,10 +56,10 @@ import java.util.concurrent.TimeUnit;
 @Configuration
 public class WebConfig implements WebMvcConfigurer {
 
-    @Autowired(required = false)
+    @Resource
     private IConfigBiz configBiz;
 
-    @Autowired(required = false)
+    @Resource
     private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
 
     @Bean
@@ -100,7 +95,7 @@ public class WebConfig implements WebMvcConfigurer {
         String uploadMapping = MSProperties.upload.mapping;
         String uploadFolderPath = MSProperties.upload.path;
         String template = MSProperties.upload.template;
-        String htmlDir = MSProperties.htmlDir;
+        String htmlDir = MSProperties.DiyProperties.htmlDir;
         // 上传路径映射 这里的映射不能使用File.separator Windows会存在映射问题
         registry.addResourceHandler(uploadMapping).addResourceLocations("/" + uploadFolderPath + "/", "file:" + uploadFolderPath + "/");
         registry.addResourceHandler("/" + template + "/**").addResourceLocations("/" + template + "/", "file:" + template + "/");
@@ -141,13 +136,15 @@ public class WebConfig implements WebMvcConfigurer {
         registration.setName("XSSFilter");
         registration.addUrlPatterns(new String[]{"/*"});
         registration.setOrder(-2147483648);
-        xssFilter.includes.add("/**");
-        xssFilter.excludes.add(MSProperties.manager.path + "/**");
-        if (filterUrl != null && StrUtil.isNotBlank(filterUrl.toString())) {
-            xssFilter.includes.addAll(Arrays.asList(filterUrl.toString().split(",")));
+        if (filterUrl != null && StrUtil.isNotBlank(filterUrl)) {
+            xssFilter.includes.addAll(Arrays.asList(filterUrl.split(",")));
+        }else {
+            xssFilter.includes.add("/**");
         }
-        if (excludeUrl != null && StrUtil.isNotBlank(excludeUrl.toString())) {
-            xssFilter.excludes.addAll(Arrays.asList(excludeUrl.toString().split(",")));
+        if (excludeUrl != null && StrUtil.isNotBlank(excludeUrl)) {
+            xssFilter.excludes.addAll(Arrays.asList(excludeUrl.split(",")));
+        }else {
+            xssFilter.excludes.add(MSProperties.manager.path + "/**");
         }
         initParameters.put("isIncludeRichText", "false");
         registration.setInitParameters(initParameters);

+ 27 - 14
src/main/resources/application.yml

@@ -1,12 +1,15 @@
 server:
   port: 8080
   servlet.session.timeout: P0DT60M0S #D天H小时M分钟S秒,字符T是紧跟在时分秒之前的,每个单位都必须由数字开始,且时分秒顺序不能乱
+  error:
+    include-exception: true
+    include-message: always
   servlet:
     encoding:
       force: true
       charset: utf-8
       enabled: true
-#  ssl: #https证书配置 配置了之后只能通过https访问应用,此配置只争对springboot方式有效,如果使用了nginx需要在nginx配置证书
+#  ssl: #https证书配置 配置了之后只能通过https访问应用
 #    key-store: xxx.pfx 证书文件
 #    key-store-password:  1234 证书密码
 
@@ -17,8 +20,13 @@ logging:
   config: classpath:log4j-spring.xml
 
 ms:
-
-  shiro-key: d3d3bWluZ3NvZnRuZXRtcw== #生产必须修改此值否则会存在安全风险,可以通过 https://base64.us/随机生产一个Base64值
+  xss:
+    xssEnable: true #xss过滤器的开关
+    filterUrl: /**   #过滤的url,多个用逗号分开
+    excludeUrl: /ms/**,/static/**,/template/**,/file/upload.do,/static/plugins/ueditor/1.4.3.3/jsp/editor.do,/activity/saveUser.do  #排除的url,多个用逗号分开
+  #  mstore-url: http://store.i.mingsoft.net
+  #  mstore-host: store.i.mingsoft.net
+  # shiro-key:  #16位长度,不填写默认随机生成
   cookie-name: SHIRO_SESSION_ID
   html-dir: html
   rand-code:
@@ -30,20 +38,17 @@ ms:
   manager:
     path: /ms #后台访问的路径,如:http://项目/ms/login.do,生产的时候建议修改
     check-code: true #默认开启验证码验证,false验证码不验证
-  xss:
-    xssEnable: true #xss过滤器的开关
-    filterUrl: /**   #过滤的url,多个用逗号分开
-    excludeUrl: /ms**,/static**,/template**,/file/upload.do,/static/plugins/ueditor/1.4.3.3/jsp/editor.do #排除的url,多个用逗号分开
+
   upload:
     enable-web: true  #启用web层的上传
     template: template #模板文件夹支持重命名,不支持路径
     path: upload #文件上传路径,可以根据实际写绝对路径
     mapping: /upload/** #修改需要谨慎,系统第一次部署可以随意修改,如果已经有了上传数据,再次修改会导致之前上传的文件404
-    denied: .exe,.jsp,.jspx,.sh
+    denied: exe,jsp,xml,sh,bat,py
     back-up: /upload_back
     multipart:
       #最大上传文件大小 单位:KB
-      max-file-size: 10240
+      max-file-size: 1024
       #文件暂存临时目录
       upload-temp-dir: temp
       #临时文件大小
@@ -52,8 +57,20 @@ ms:
       max-request-size: -1
 
 spring:
+  main:
+    allow-circular-references: true
   datasource:
     druid:
+      initialSize: 5 #初始连接数,默认0
+      minIdle: 5  #最小连接数,默认8
+      maxActive: 20 #最大连接数,默认8
+      maxWait: 2000 #获取连接的最大等待时间,单位毫秒
+      validationQuery: SELECT 1
+      testOnBorrow: true #设置从连接池获取连接时是否检查连接有效性,true检查,false不检查
+      testOnReturn: true #设置从连接池归还连接时是否检查连接有效性,true检查,false不检查
+      poolPreparedStatements: true #可以支持PSCache(提升写入、查询效率)
+      filters: stat,wall #配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
+      keepAlive: true #保持长连接
       stat-view-servlet:
         enabled: false #启用druid监控
   profiles:
@@ -63,6 +80,7 @@ spring:
       config: classpath:ehcache.xml
   mvc:
     pathmatch:
+      matching-strategy: ANT_PATH_MATCHER
       use-suffix-pattern: true
   devtools:
     restart:
@@ -92,11 +110,6 @@ spring:
       time_format: HH:mm:ss
       datetime_format: yyyy-MM-dd HH:mm:ss
       number_format: 0.##
-  http:
-    encoding:
-      force: true
-      charset: utf-8
-      enabled: true
 
 mybatis-plus:
   global-config: