GenerateHtmlImpl.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. package com.caimei.www.service.generate.impl;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.caimei.www.pojo.page.BaseLink;
  5. import com.caimei.www.pojo.page.ImageLink;
  6. import com.caimei.www.pojo.page.TopMenu;
  7. import com.caimei.www.service.generate.GenerateHtml;
  8. import com.caimei.www.service.page.BaseService;
  9. import com.caimei.www.service.page.HomeService;
  10. import com.caimei.www.service.page.ProductService;
  11. import com.caimei.www.service.page.SinglePageService;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.apache.commons.io.FileUtils;
  14. import org.springframework.beans.factory.annotation.Value;
  15. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  16. import org.springframework.core.io.support.ResourcePatternResolver;
  17. import org.springframework.stereotype.Service;
  18. import org.springframework.web.server.ServerWebExchange;
  19. import org.thymeleaf.TemplateEngine;
  20. import org.thymeleaf.spring5.context.webflux.SpringWebFluxContext;
  21. import org.thymeleaf.util.StringUtils;
  22. import javax.annotation.Resource;
  23. import java.io.*;
  24. import java.net.URL;
  25. import java.net.URLConnection;
  26. import java.util.HashMap;
  27. import java.util.List;
  28. import java.util.Map;
  29. /**
  30. * Description
  31. *
  32. * @author : Charles
  33. * @date : 2021/5/7
  34. */
  35. @Slf4j
  36. @Service
  37. public class GenerateHtmlImpl implements GenerateHtml {
  38. @Value("${caimei.destPath}")
  39. private String destPath;
  40. @Value("${caimei.coreServer}")
  41. private String coreServer;
  42. @Value("${caimei.spiServer}")
  43. private String spiServer;
  44. /** 打包时间 */
  45. @Value("${caimei.siteEnv}")
  46. private String siteEnv;
  47. /** 打包时间 */
  48. @Value("${spring.application.build-time}")
  49. private String buildTime;
  50. @Resource
  51. private TemplateEngine templateEngine;
  52. @Resource
  53. private BaseService baseService;
  54. @Resource
  55. private HomeService homeService;
  56. @Resource
  57. private SinglePageService singlePageService;
  58. @Resource
  59. private ProductService productService;
  60. /**
  61. * 生成静态首页
  62. */
  63. @Override
  64. public String generateStaticHome(ServerWebExchange exchange) {
  65. // 上下文
  66. SpringWebFluxContext context = new SpringWebFluxContext(exchange);
  67. // 设置页面数据
  68. context.setVariables(setStaticHomeData());
  69. // 输出流
  70. File dest = new File(destPath, "index.html");
  71. if (dest.exists()) {
  72. boolean delete = dest.delete();
  73. }
  74. try (PrintWriter writer = new PrintWriter(dest, "UTF-8")) {
  75. // 生成html
  76. templateEngine.process("index", context, writer);
  77. log.info("[静态页服务]:生成静态首页成功! ^_^");
  78. return "[静态页服务]:生成静态首页成功! ^_^";
  79. } catch (Exception e) {
  80. boolean delete = dest.delete();
  81. log.error("[静态页服务]:生成静态首页异常!", e);
  82. return "[静态页服务]:生成静态首页异常!"+e.toString();
  83. }
  84. }
  85. /**
  86. * 生成产品仪器页面
  87. * @param pageId 页面Id
  88. */
  89. @Override
  90. public String generateProductType(ServerWebExchange exchange, Integer pageId){
  91. if (pageId == null) {
  92. return "pageId不能为空!";
  93. }
  94. // 上下文
  95. SpringWebFluxContext context = new SpringWebFluxContext(exchange);
  96. // 设置页面数据
  97. context.setVariables(setStaticProductType(pageId));
  98. // 输出流 /product/type-287.html
  99. File dest = new File(destPath + "/product", "type-"+pageId+".html");
  100. if (dest.exists()) {
  101. boolean delete = dest.delete();
  102. }
  103. try (PrintWriter writer = new PrintWriter(dest, "UTF-8")) {
  104. // 生成html
  105. templateEngine.process("product/instrument", context, writer);
  106. log.info("[静态页服务]:生成静态产品仪器页("+pageId+")成功! ^_^");
  107. return "[静态页服务]:生成静态产品仪器页("+pageId+")成功! ^_^";
  108. } catch (Exception e) {
  109. boolean delete = dest.delete();
  110. log.error("[静态页服务]:生成静态产品仪器页("+pageId+")异常!", e);
  111. return "[静态页服务]:生成静态产品仪器页("+pageId+")异常!"+e.toString();
  112. }
  113. }
  114. /**
  115. * 拷贝静态资源文件
  116. */
  117. @Override
  118. public String generateStaticFiles() {
  119. // 拷贝静态资源文件
  120. try {
  121. copyResourceToFile();
  122. log.info("[静态页服务]:拷贝静态资源文件成功! ^_^");
  123. return "[静态页服务]:拷贝静态资源文件成功! ^_^";
  124. } catch (Exception e) {
  125. log.error("[静态页服务]:拷贝静态资源文件异常!", e);
  126. return "[静态页服务]:拷贝静态资源文件异常!"+e.toString();
  127. }
  128. }
  129. /**
  130. * 设置静态首页数据
  131. */
  132. private Map<String, Object> setStaticHomeData() {
  133. Map<String, Object> map = new HashMap<>();
  134. // 环境变量,(2:正式环境,1:测试环境,0:开发环境)
  135. map.put("siteEnv", siteEnv);
  136. map.put("agent", "");
  137. // 静态文件版本号
  138. map.put("version", buildTime);
  139. // spi服务器地址
  140. map.put("coreServer", coreServer);
  141. map.put("spiServer", spiServer);
  142. // 搜索热门关键字
  143. List<String> searchHotWord = baseService.getSearchHotWord();
  144. map.put("searchHotWord", searchHotWord);
  145. // 头部菜单
  146. List<TopMenu> menuList = baseService.getNavMenu();
  147. map.put("topMenuList", menuList);
  148. // 分类菜单
  149. List<JSONObject> classifyList = baseService.getClassifyJson();
  150. map.put("classifyJson", classifyList);
  151. // 底部帮助页
  152. List<BaseLink> helpPages = baseService.getHelpPages();
  153. map.put("helpPages", helpPages);
  154. // 友情链接
  155. List<BaseLink> friendLinks = baseService.getFriendLinks();
  156. map.put("friendLinks", friendLinks);
  157. // 获取banner图
  158. List<ImageLink> bannerList = homeService.getHomeBanners();
  159. map.put("bannerList", bannerList);
  160. // 首页楼层
  161. Map<String, Object> floorMap = homeService.getHomeFloors();
  162. map.put("floorJson", floorMap);
  163. // 右侧侧边栏数据
  164. Map<String, Object> sideMap = homeService.getHomeSideJson();
  165. map.put("sideJson", sideMap);
  166. log.debug(map.toString());
  167. return map;
  168. }
  169. private Map<String, Object> setStaticProductType(Integer pageId) {
  170. Map<String, Object> map = new HashMap<>();
  171. // 环境变量,(2:正式环境,1:测试环境,0:开发环境)
  172. map.put("siteEnv", siteEnv);
  173. map.put("agent", "");
  174. // 静态文件版本号
  175. map.put("version", buildTime);
  176. // spi服务器地址
  177. map.put("coreServer", coreServer);
  178. map.put("spiServer", spiServer);
  179. // 搜索热门关键字
  180. List<String> searchHotWord = baseService.getSearchHotWord();
  181. map.put("searchHotWord", searchHotWord);
  182. // 头部菜单
  183. List<TopMenu> menuList = baseService.getNavMenu();
  184. map.put("topMenuList", menuList);
  185. // 分类菜单
  186. List<JSONObject> classifyList = baseService.getClassifyJson();
  187. map.put("classifyJson", classifyList);
  188. // 底部帮助页
  189. List<BaseLink> helpPages = baseService.getHelpPages();
  190. map.put("helpPages", helpPages);
  191. // 友情链接
  192. List<BaseLink> friendLinks = baseService.getFriendLinks();
  193. map.put("friendLinks", friendLinks);
  194. String title = singlePageService.getPageTitleById(pageId);
  195. map.put("pageId", pageId);
  196. map.put("pageTitle", title);
  197. Integer typeSort = singlePageService.getPageTypeSort(pageId);
  198. map.put("typeSort", typeSort);
  199. // 产品仪器一级分类
  200. JSONArray classifyArr = productService.getTypeClassifyJson(typeSort);
  201. // 产品仪器楼层数据
  202. Map<String, Object> floorMap = productService.getTypeFloorJson(pageId);
  203. map.put("bigTypeJson", classifyArr);
  204. map.put("typeFloorJson", floorMap);
  205. log.debug(map.toString());
  206. return map;
  207. }
  208. /**
  209. * 资源清单获取并拷贝
  210. */
  211. private void copyResourceToFile() throws IOException {
  212. // 资源清单获取
  213. ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  214. org.springframework.core.io.Resource[] resources = resolver.getResources("static/**");
  215. for (org.springframework.core.io.Resource resource : resources) {
  216. String fileName = resource.getFilename();
  217. assert fileName != null;
  218. if (fileName.indexOf(".") > 0) {
  219. InputStream inputStream = null;
  220. try {
  221. inputStream = resource.getInputStream();
  222. } catch (Exception e) {
  223. log.warn(String.format("[%s]获取输入流发生异常!", resource.getURL()));
  224. throw new RuntimeException(String.format("[%s]获取输入流发生异常!", resource.getURL()));
  225. }
  226. //分析相对目录
  227. String tempPath = "";
  228. String[] urls = resource.getURL().toString().split("/static/");
  229. if (urls.length >= 2 ){
  230. tempPath = urls[urls.length-1];
  231. } else {
  232. throw new RuntimeException("relativeRootPath有误:无法分析相对目录");
  233. }
  234. tempPath = tempPath.substring(0, tempPath.length() - fileName.length());
  235. if (StringUtils.isEmpty(tempPath)) {
  236. tempPath = File.separator;
  237. }
  238. String filePath = destPath + File.separator + tempPath;
  239. if (createDir(filePath)) {
  240. String destName = filePath + fileName;
  241. // 输出流
  242. File dest = new File(destName);
  243. if (dest.exists()) {
  244. boolean delete = dest.delete();
  245. }
  246. FileUtils.copyInputStreamToFile(inputStream, dest);
  247. } else {
  248. throw new RuntimeException(String.format("创建本地目录[%s]失败!", resource.getURL()));
  249. }
  250. }
  251. }
  252. }
  253. /**
  254. * 创建目录
  255. */
  256. private static boolean createDir(String dirName) {
  257. File dir = new File(dirName);
  258. if (dir.exists()) {
  259. return true;
  260. }
  261. if (!dirName.endsWith(File.separator)) {
  262. dirName = dirName + File.separator;
  263. }
  264. if (dir.mkdirs()) {
  265. log.warn("创建目录" + dirName + "成功!");
  266. return true;
  267. } else {
  268. log.warn("创建目录" + dirName + "失败!");
  269. return false;
  270. }
  271. }
  272. public static void download(String urlString, String filename,String savePath) throws Exception {
  273. // 构造URL
  274. URL url = new URL(urlString);
  275. // 打开连接
  276. URLConnection con = url.openConnection();
  277. //设置请求超时为5s
  278. con.setConnectTimeout(5*1000);
  279. // 输入流
  280. InputStream is = con.getInputStream();
  281. // 1K的数据缓冲
  282. byte[] bs = new byte[1024];
  283. // 读取到的数据长度
  284. int len;
  285. // 输出的文件流
  286. File sf=new File(savePath);
  287. if(!sf.exists()){
  288. sf.mkdirs();
  289. }
  290. OutputStream os = new FileOutputStream(sf.getPath()+"\\"+filename);
  291. // 开始读取
  292. while ((len = is.read(bs)) != -1) {
  293. os.write(bs, 0, len);
  294. }
  295. // 完毕,关闭所有链接
  296. os.close();
  297. is.close();
  298. }
  299. }