CmsParserUtil.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /**
  2. * The MIT License (MIT)
  3. * Copyright (c) 2020 铭软科技(mingsoft.net)
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. * The above copyright notice and this permission notice shall be included in all
  11. * copies or substantial portions of the Software.
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  14. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  15. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  16. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  17. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. */
  19. package net.mingsoft.cms.util;
  20. import cn.hutool.core.collection.CollUtil;
  21. import cn.hutool.core.io.FileUtil;
  22. import cn.hutool.core.util.PageUtil;
  23. import freemarker.core.ParseException;
  24. import freemarker.template.MalformedTemplateNameException;
  25. import freemarker.template.TemplateNotFoundException;
  26. import net.mingsoft.base.constant.Const;
  27. import net.mingsoft.basic.util.BasicUtil;
  28. import net.mingsoft.basic.util.SpringUtil;
  29. import net.mingsoft.cms.bean.CategoryBean;
  30. import net.mingsoft.cms.constant.e.CategoryTypeEnum;
  31. import net.mingsoft.cms.entity.CategoryEntity;
  32. import net.mingsoft.mdiy.bean.PageBean;
  33. import net.mingsoft.mdiy.biz.IModelBiz;
  34. import net.mingsoft.mdiy.biz.impl.ModelBizImpl;
  35. import net.mingsoft.mdiy.entity.ModelEntity;
  36. import net.mingsoft.mdiy.util.ParserUtil;
  37. import org.apache.commons.lang3.StringUtils;
  38. import javax.servlet.http.HttpServletRequest;
  39. import java.io.File;
  40. import java.io.IOException;
  41. import java.util.ArrayList;
  42. import java.util.HashMap;
  43. import java.util.List;
  44. import java.util.Map;
  45. import java.util.concurrent.ExecutorService;
  46. /**
  47. * 文章解析工具类
  48. */
  49. public class CmsParserUtil {
  50. private final static String FIELD = "field";
  51. /**
  52. * 指定模板,指定路径进行生成静态页面,会自定识别pc与移动端
  53. *
  54. * @param templatePath 模板路径
  55. * @param targetPath 生成后的路径,默认生成的html文件,所以不能带.html后缀,
  56. * @throws IOException
  57. */
  58. public static void generate(String templatePath, String targetPath, String htmlDir) throws IOException {
  59. Map<String, Object> map = new HashMap<String, Object>();
  60. map.put(ParserUtil.IS_DO, false);
  61. CategoryEntity column = new CategoryEntity();
  62. //内容管理栏目编码
  63. map.put(ParserUtil.COLUMN, column);
  64. map.put(ParserUtil.HTML, htmlDir);
  65. //站点编号
  66. if (BasicUtil.getWebsiteApp() != null) {
  67. map.put(ParserUtil.APP_DIR, BasicUtil.getWebsiteApp().getAppDir());
  68. map.put(ParserUtil.URL, BasicUtil.getWebsiteApp().getAppHostUrl());
  69. map.put(ParserUtil.APP_ID, BasicUtil.getWebsiteApp().getAppId());
  70. } else {
  71. map.put(ParserUtil.URL, BasicUtil.getUrl());
  72. map.put(ParserUtil.APP_DIR, BasicUtil.getApp().getAppDir());
  73. }
  74. String content = ParserUtil.rendering(templatePath, map);
  75. FileUtil.writeString(content, ParserUtil.buildHtmlPath(targetPath, htmlDir, map.get(ParserUtil.APP_DIR).toString()), Const.UTF8);
  76. }
  77. /**
  78. * 生成静态列表页
  79. *
  80. * @param column
  81. * @param articleIdTotal
  82. * @throws TemplateNotFoundException
  83. * @throws MalformedTemplateNameException
  84. * @throws ParseException
  85. * @throws IOException
  86. */
  87. public static void generateList(CategoryEntity column, int articleIdTotal, String htmlDir)
  88. throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
  89. try {
  90. // 文章的栏目模型编号
  91. PageBean page = new PageBean();
  92. //获取列表中的size
  93. page.setSize(ParserUtil.getPageSize(column.getCategoryListUrl(), 20));
  94. page.setRcount(articleIdTotal);
  95. int totalPageSize = PageUtil.totalPage(articleIdTotal, page.getSize());
  96. page.setTotal(totalPageSize);
  97. //全局参数设置
  98. Map<String, Object> parserParams = new HashMap<String, Object>();
  99. parserParams.put(ParserUtil.IS_DO, false);
  100. parserParams.put(ParserUtil.HTML, htmlDir);
  101. parserParams.put(ParserUtil.PAGE, page);
  102. //站点编号
  103. if (BasicUtil.getWebsiteApp() != null) {
  104. parserParams.put(ParserUtil.APP_DIR, BasicUtil.getWebsiteApp().getAppDir());
  105. parserParams.put(ParserUtil.URL, BasicUtil.getWebsiteApp().getAppHostUrl());
  106. parserParams.put(ParserUtil.APP_ID, BasicUtil.getWebsiteApp().getAppId());
  107. } else {
  108. parserParams.put(ParserUtil.URL, BasicUtil.getUrl());
  109. parserParams.put(ParserUtil.APP_DIR, BasicUtil.getApp().getAppDir());
  110. }
  111. parserParams.put(ParserUtil.COLUMN, column);
  112. //标签中使用field获取当前栏目
  113. parserParams.put(ParserUtil.FIELD, column);
  114. String columnListPath;
  115. ModelEntity contentModel = null;
  116. // 判断当前栏目是否有自定义模型
  117. if (column.getMdiyModelId() != null) {
  118. // 通过栏目模型编号获取自定义模型实体
  119. contentModel = (ModelEntity) SpringUtil.getBean(ModelBizImpl.class).getEntity(column.getMdiyModelId());
  120. }
  121. if (contentModel != null) {
  122. // 将自定义模型编号设置为key值
  123. parserParams.put(ParserUtil.TABLE_NAME, contentModel.getModelTableName());
  124. }
  125. int pageNo = 1;
  126. //文章列表页没有写文章列表标签,总数为0
  127. if (totalPageSize <= 0) {
  128. // 数据库中第一页是从开始0*size
  129. columnListPath = ParserUtil.buildHtmlPath(column.getCategoryPath() + File.separator + ParserUtil.INDEX, htmlDir, parserParams.get(ParserUtil.APP_DIR).toString());
  130. // 设置分页的起始位置
  131. page.setPageNo(pageNo);
  132. String read = ParserUtil.rendering(File.separator + column.getCategoryListUrl(), parserParams);
  133. FileUtil.writeString(read, columnListPath, Const.UTF8);
  134. } else {
  135. // 遍历分页
  136. for (int i = 0; i < totalPageSize; i++) {
  137. if (i == 0) {
  138. // 数据库中第一页是从开始0*size
  139. // 首页路径index.html
  140. columnListPath = ParserUtil
  141. .buildHtmlPath(column.getCategoryPath() + File.separator + ParserUtil.INDEX, htmlDir, parserParams.get(ParserUtil.APP_DIR).toString());
  142. } else {
  143. // 其他路径list-2.html
  144. columnListPath = ParserUtil
  145. .buildHtmlPath(column.getCategoryPath() + File.separator + ParserUtil.PAGE_LIST + pageNo, htmlDir, parserParams.get(ParserUtil.APP_DIR).toString());
  146. }
  147. // 设置分页的起始位置
  148. page.setPageNo(pageNo);
  149. String read = ParserUtil.rendering(File.separator + column.getCategoryListUrl(), parserParams);
  150. FileUtil.writeString(read, columnListPath, Const.UTF8);
  151. pageNo++;
  152. }
  153. }
  154. } catch (Exception e) {
  155. e.printStackTrace();
  156. }
  157. }
  158. /**
  159. * 生成内容
  160. *
  161. * @param articleIdList 文章集合
  162. * @return
  163. * @throws IOException
  164. * @throws ParseException
  165. * @throws MalformedTemplateNameException
  166. * @throws TemplateNotFoundException
  167. */
  168. public static void generateBasic(List<CategoryBean> articleIdList, String htmlDir) {
  169. Map<String, Object> parserParams = new HashMap<String, Object>();
  170. parserParams.put(ParserUtil.IS_DO, false);
  171. if (BasicUtil.getWebsiteApp() != null) {
  172. parserParams.put(ParserUtil.APP_DIR, BasicUtil.getWebsiteApp().getAppDir());
  173. parserParams.put(ParserUtil.URL, BasicUtil.getWebsiteApp().getAppHostUrl());
  174. parserParams.put(ParserUtil.APP_ID, BasicUtil.getWebsiteApp().getAppId());
  175. } else {
  176. parserParams.put(ParserUtil.URL, BasicUtil.getUrl());
  177. parserParams.put(ParserUtil.APP_DIR, BasicUtil.getApp().getAppDir());
  178. }
  179. parserParams.put(ParserUtil.HTML, htmlDir);
  180. Map<Object, Object> contentModelMap = new HashMap<Object, Object>();
  181. ModelEntity contentModel = null;
  182. // 记录已经生成了文章编号
  183. List<String> generateIds = new ArrayList<>();
  184. // 生成文章
  185. for (int artId = 0; artId < articleIdList.size(); ) {
  186. CategoryBean categoryBean = articleIdList.get(artId);
  187. String writePath = null;
  188. //设置分页类
  189. PageBean page = new PageBean();
  190. // 文章编号
  191. String articleId = categoryBean.getArticleId();
  192. // 文章的栏目路径
  193. String articleColumnPath = categoryBean.getCategoryPath();
  194. // 该文章相关分类
  195. String categoryParentId = categoryBean.getId();
  196. if (StringUtils.isNotBlank(categoryBean.getCategoryParentIds())) {
  197. categoryParentId += ',' + categoryBean.getCategoryParentIds();
  198. }
  199. // 文章的模板路径
  200. String columnUrl = categoryBean.getCategoryUrl();
  201. // 文章的栏目模型编号
  202. Integer columnContentModelId = null;
  203. if (articleIdList.get(artId).getMdiyModelId() != null && categoryBean.getMdiyModelId() > 0) {
  204. columnContentModelId = categoryBean.getMdiyModelId();
  205. }
  206. // 文章是否已经生成了,生成了就跳过
  207. if (generateIds.contains(articleId)) {
  208. artId++;
  209. continue;
  210. }
  211. // 判断文件是否存在,若不存在弹出返回信息
  212. if (!FileUtil.exist(ParserUtil.buildTempletPath(columnUrl)) || categoryBean.getId() == null || categoryBean.getCategoryType() == null) {
  213. artId++;
  214. continue;
  215. }
  216. // 将
  217. generateIds.add(articleId);
  218. //如果是封面就生成index.html
  219. if (categoryBean.getCategoryType().equals(CategoryTypeEnum.COVER.toString())) {
  220. writePath = ParserUtil.buildHtmlPath(articleColumnPath + File.separator + ParserUtil.INDEX, htmlDir, parserParams.get(ParserUtil.APP_DIR).toString());
  221. } else {
  222. // 组合文章路径如:html/站点id/栏目id/文章id.html
  223. writePath = ParserUtil.buildHtmlPath(articleColumnPath + File.separator + articleId, htmlDir, parserParams.get(ParserUtil.APP_DIR).toString());
  224. }
  225. parserParams.put(ParserUtil.COLUMN, categoryBean);
  226. // 判断当前栏目是否有自定义模型
  227. if (columnContentModelId != null) {
  228. // 通过当前栏目的模型编号获取,自定义模型表名
  229. if (contentModelMap.containsKey(columnContentModelId)) {
  230. parserParams.put(ParserUtil.TABLE_NAME, contentModel.getModelTableName());
  231. } else {
  232. // 通过栏目模型编号获取自定义模型实体
  233. contentModel = (ModelEntity) SpringUtil.getBean(IModelBiz.class)
  234. .getEntity(columnContentModelId);
  235. // 将自定义模型编号设置为key值
  236. contentModelMap.put(columnContentModelId, contentModel.getModelTableName());
  237. parserParams.put(ParserUtil.TABLE_NAME, contentModel.getModelTableName());
  238. }
  239. }
  240. parserParams.put(ParserUtil.ID, articleId);
  241. // 第一篇文章没有上一篇
  242. if (artId > 0) {
  243. CategoryBean preCaBean = articleIdList.get(artId - 1);
  244. //判断当前文档是否与上一页文章在同一栏目下,并且不能使用父栏目字符串,因为父栏目中没有所属栏目编号
  245. // if( categoryParentId.contains(preCaBean.getCategoryId()+"")){
  246. page.setPreId(preCaBean.getArticleId());
  247. // }
  248. }
  249. // 最后一篇文章没有下一篇
  250. if (artId + 1 < articleIdList.size()) {
  251. CategoryBean nextCaBean = articleIdList.get(artId + 1);
  252. //判断当前文档是否与下一页文章在同一栏目下并且不能使用父栏目字符串,因为父栏目中没有所属栏目编号
  253. // if(categoryParentId.contains(nextCaBean.getCategoryId()+"")){
  254. page.setNextId(nextCaBean.getArticleId());
  255. // }
  256. }
  257. parserParams.put(ParserUtil.PAGE, page);
  258. String finalWritePath = writePath;
  259. HashMap<Object, Object> cloneMap = CollUtil.newHashMap();
  260. cloneMap.putAll(parserParams);
  261. HttpServletRequest request = SpringUtil.getRequest();
  262. String content = null;
  263. try {
  264. content = ParserUtil.rendering(columnUrl, cloneMap);
  265. FileUtil.writeString(content, finalWritePath, Const.UTF8);
  266. } catch (IOException e) {
  267. e.printStackTrace();
  268. }
  269. artId++;
  270. }
  271. }
  272. }