package com.caimei.www.service.generate.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.caimei.www.pojo.page.BaseLink; import com.caimei.www.pojo.page.ImageLink; import com.caimei.www.pojo.page.TopMenu; import com.caimei.www.service.generate.GenerateHtml; import com.caimei.www.service.page.BaseService; import com.caimei.www.service.page.HomeService; import com.caimei.www.service.page.ProductService; import com.caimei.www.service.page.SinglePageService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.stereotype.Service; import org.springframework.web.server.ServerWebExchange; import org.thymeleaf.TemplateEngine; import org.thymeleaf.spring5.context.webflux.SpringWebFluxContext; import org.thymeleaf.util.StringUtils; import javax.annotation.Resource; import java.io.*; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Description * * @author : Charles * @date : 2021/5/7 */ @Slf4j @Service public class GenerateHtmlImpl implements GenerateHtml { @Value("${caimei.destPath}") private String destPath; @Value("${caimei.coreServer}") private String coreServer; @Value("${caimei.spiServer}") private String spiServer; /** 打包时间 */ @Value("${caimei.siteEnv}") private String siteEnv; /** 打包时间 */ @Value("${spring.application.build-time}") private String buildTime; @Resource private TemplateEngine templateEngine; @Resource private BaseService baseService; @Resource private HomeService homeService; @Resource private SinglePageService singlePageService; @Resource private ProductService productService; /** * 生成静态首页 */ @Override public String generateStaticHome(ServerWebExchange exchange) { // 上下文 SpringWebFluxContext context = new SpringWebFluxContext(exchange); // 设置页面数据 context.setVariables(setStaticHomeData()); // 输出流 File dest = new File(destPath, "index.html"); if (dest.exists()) { boolean delete = dest.delete(); } try (PrintWriter writer = new PrintWriter(dest, "UTF-8")) { // 生成html templateEngine.process("index", context, writer); log.info("[静态页服务]:生成静态首页成功! ^_^"); return "[静态页服务]:生成静态首页成功! ^_^"; } catch (Exception e) { boolean delete = dest.delete(); log.error("[静态页服务]:生成静态首页异常!", e); return "[静态页服务]:生成静态首页异常!"+e.toString(); } } /** * 生成产品仪器页面 * @param pageId 页面Id */ @Override public String generateProductType(ServerWebExchange exchange, Integer pageId){ if (pageId == null) { return "pageId不能为空!"; } // 上下文 SpringWebFluxContext context = new SpringWebFluxContext(exchange); // 设置页面数据 context.setVariables(setStaticProductType(pageId)); // 输出流 /product/type-287.html File dest = new File(destPath + "/product", "type-"+pageId+".html"); if (dest.exists()) { boolean delete = dest.delete(); } try (PrintWriter writer = new PrintWriter(dest, "UTF-8")) { // 生成html templateEngine.process("product/instrument", context, writer); log.info("[静态页服务]:生成静态产品仪器页("+pageId+")成功! ^_^"); return "[静态页服务]:生成静态产品仪器页("+pageId+")成功! ^_^"; } catch (Exception e) { boolean delete = dest.delete(); log.error("[静态页服务]:生成静态产品仪器页("+pageId+")异常!", e); return "[静态页服务]:生成静态产品仪器页("+pageId+")异常!"+e.toString(); } } /** * 拷贝静态资源文件 */ @Override public String generateStaticFiles() { // 拷贝静态资源文件 try { copyResourceToFile(); log.info("[静态页服务]:拷贝静态资源文件成功! ^_^"); return "[静态页服务]:拷贝静态资源文件成功! ^_^"; } catch (Exception e) { log.error("[静态页服务]:拷贝静态资源文件异常!", e); return "[静态页服务]:拷贝静态资源文件异常!"+e.toString(); } } /** * 设置静态首页数据 */ private Map setStaticHomeData() { Map map = new HashMap<>(); // 环境变量,(2:正式环境,1:测试环境,0:开发环境) map.put("siteEnv", siteEnv); map.put("agent", ""); // 静态文件版本号 map.put("version", buildTime); // spi服务器地址 map.put("coreServer", coreServer); map.put("spiServer", spiServer); // 搜索热门关键字 List searchHotWord = baseService.getSearchHotWord(); map.put("searchHotWord", searchHotWord); // 头部菜单 List menuList = baseService.getNavMenu(); map.put("topMenuList", menuList); // 分类菜单 List classifyList = baseService.getClassifyJson(); map.put("classifyJson", classifyList); // 底部帮助页 List helpPages = baseService.getHelpPages(); map.put("helpPages", helpPages); // 友情链接 List friendLinks = baseService.getFriendLinks(); map.put("friendLinks", friendLinks); // 获取banner图 List bannerList = homeService.getHomeBanners(); map.put("bannerList", bannerList); // 首页楼层 Map floorMap = homeService.getHomeFloors(); map.put("floorJson", floorMap); // 右侧侧边栏数据 Map sideMap = homeService.getHomeSideJson(); map.put("sideJson", sideMap); log.debug(map.toString()); return map; } private Map setStaticProductType(Integer pageId) { Map map = new HashMap<>(); // 环境变量,(2:正式环境,1:测试环境,0:开发环境) map.put("siteEnv", siteEnv); map.put("agent", ""); // 静态文件版本号 map.put("version", buildTime); // spi服务器地址 map.put("coreServer", coreServer); map.put("spiServer", spiServer); // 搜索热门关键字 List searchHotWord = baseService.getSearchHotWord(); map.put("searchHotWord", searchHotWord); // 头部菜单 List menuList = baseService.getNavMenu(); map.put("topMenuList", menuList); // 分类菜单 List classifyList = baseService.getClassifyJson(); map.put("classifyJson", classifyList); // 底部帮助页 List helpPages = baseService.getHelpPages(); map.put("helpPages", helpPages); // 友情链接 List friendLinks = baseService.getFriendLinks(); map.put("friendLinks", friendLinks); String title = singlePageService.getPageTitleById(pageId); map.put("pageId", pageId); map.put("pageTitle", title); Integer typeSort = singlePageService.getPageTypeSort(pageId); map.put("typeSort", typeSort); // 产品仪器一级分类 JSONArray classifyArr = productService.getTypeClassifyJson(typeSort); // 产品仪器楼层数据 Map floorMap = productService.getTypeFloorJson(pageId); map.put("bigTypeJson", classifyArr); map.put("typeFloorJson", floorMap); log.debug(map.toString()); return map; } /** * 资源清单获取并拷贝 */ private void copyResourceToFile() throws IOException { // 资源清单获取 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); org.springframework.core.io.Resource[] resources = resolver.getResources("static/**"); for (org.springframework.core.io.Resource resource : resources) { String fileName = resource.getFilename(); assert fileName != null; if (fileName.indexOf(".") > 0) { InputStream inputStream = null; try { inputStream = resource.getInputStream(); } catch (Exception e) { log.warn(String.format("[%s]获取输入流发生异常!", resource.getURL())); throw new RuntimeException(String.format("[%s]获取输入流发生异常!", resource.getURL())); } //分析相对目录 String tempPath = ""; String[] urls = resource.getURL().toString().split("/static/"); if (urls.length >= 2 ){ tempPath = urls[urls.length-1]; } else { throw new RuntimeException("relativeRootPath有误:无法分析相对目录"); } tempPath = tempPath.substring(0, tempPath.length() - fileName.length()); if (StringUtils.isEmpty(tempPath)) { tempPath = File.separator; } String filePath = destPath + File.separator + tempPath; if (createDir(filePath)) { String destName = filePath + fileName; // 输出流 File dest = new File(destName); if (dest.exists()) { boolean delete = dest.delete(); } FileUtils.copyInputStreamToFile(inputStream, dest); } else { throw new RuntimeException(String.format("创建本地目录[%s]失败!", resource.getURL())); } } } } /** * 创建目录 */ private static boolean createDir(String dirName) { File dir = new File(dirName); if (dir.exists()) { return true; } if (!dirName.endsWith(File.separator)) { dirName = dirName + File.separator; } if (dir.mkdirs()) { log.warn("创建目录" + dirName + "成功!"); return true; } else { log.warn("创建目录" + dirName + "失败!"); return false; } } public static void download(String urlString, String filename,String savePath) throws Exception { // 构造URL URL url = new URL(urlString); // 打开连接 URLConnection con = url.openConnection(); //设置请求超时为5s con.setConnectTimeout(5*1000); // 输入流 InputStream is = con.getInputStream(); // 1K的数据缓冲 byte[] bs = new byte[1024]; // 读取到的数据长度 int len; // 输出的文件流 File sf=new File(savePath); if(!sf.exists()){ sf.mkdirs(); } OutputStream os = new FileOutputStream(sf.getPath()+"\\"+filename); // 开始读取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } // 完毕,关闭所有链接 os.close(); is.close(); } }