GenerateHtmlImpl.java 8.7 KB

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