项目 cg day07
第7章 Thymeleaf、Rabbitmq实现静态页
学习目标
-
Thymeleaf的介绍
-
Thymeleaf的入门
-
Thymeleaf的语法及标签
-
商品详情页静态化工程搭建
-
商品详情页静态化功能实现
1.详情页静态化操作 2.填充基础数据 Spu、List<Sku> 3.规格切换
搜索页面渲染
1.数据展示 2.搜索条件展示 3.实现条件搜索控制
- 用户修改商品信息,同步更新创建商品详情页
1.Thymeleaf介绍
thymeleaf是一个XML/XHTML/HTML5模板引擎,可用于Web与非Web环境中的应用开发。它是一个开源的Java库,基于Apache License 2.0许可,由Daniel Fernández创建,该作者还是Java加密库Jasypt的作者。
Thymeleaf提供了一个用于整合Spring MVC的可选模块,在应用开发中,你可以使用Thymeleaf来完全代替JSP或其他模板引擎,如Velocity、FreeMarker等。Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。相对于编写逻辑或代码,开发者只需将标签属性添加到模板中即可。接下来,这些标签属性就会在DOM(文档对象模型)上执行预先制定好的逻辑。
它的特点便是:开箱即用,Thymeleaf允许您处理六种模板,每种模板称为模板模式:
- XML
- 有效的XML
- XHTML
- 有效的XHTML
- HTML5
- 旧版HTML5
所有这些模式都指的是格式良好的XML文件,但Legacy HTML5模式除外,它允许您处理HTML5文件,其中包含独立(非关闭)标记,没有值的标记属性或不在引号之间写入的标记属性。为了在这种特定模式下处理文件,Thymeleaf将首先执行转换,将您的文件转换为格式良好的XML文件,这些文件仍然是完全有效的HTML5(实际上是创建HTML5代码的推荐方法)1。
另请注意,验证仅适用于XML和XHTML模板。
然而,这些并不是Thymeleaf可以处理的唯一模板类型,并且用户始终能够通过指定在此模式下解析模板的方法和编写结果的方式来定义他/她自己的模式。这样,任何可以建模为DOM树(无论是否为XML)的东西都可以被Thymeleaf有效地作为模板处理。
2.Springboot整合thymeleaf
使用springboot 来集成使用Thymeleaf可以大大减少单纯使用thymleaf的代码量,所以我们接下来使用springboot集成使用thymeleaf.
实现的步骤为:
- 创建一个sprinboot项目
- 添加thymeleaf的起步依赖
- 添加spring web的起步依赖
- 编写html 使用thymleaf的语法获取变量对应后台传递的值
- 编写controller 设置变量的值到model中
(1)创建工程
创建一个独立的工程springboot-thymeleaf,该工程为案例工程,不需要放到changgou-parent工程中。
pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itheima</groupId><artifactId>springboot-thymeleaf</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.4.RELEASE</version></parent><dependencies><!--web起步依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--thymeleaf配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency></dependencies>
</project>
(2)创建html
在resources中创建templates目录,在templates目录创建 demo1.html,代码如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Thymeleaf的入门</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<!--输出hello数据-->
<p th:text="${hello}"></p>
</body>
</html>
解释:
<html xmlns:th="http://www.thymeleaf.org">
:这句声明使用thymeleaf标签
<p th:text="${hello}"></p>
:这句使用 th:text="${变量名}" 表示 使用thymeleaf获取文本数据,类似于EL表达式。
(3)修改application.yml配置
创建application.yml,并设置thymeleaf的缓存设置,设置为false。默认加缓存的,用于测试。
spring:thymeleaf:cache: false
在这里,其实还有一些默认配置,比如视图前缀:classpath:/templates/,视图后缀:.html
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties
部分源码如下:
(4)控制层
创建controller用于测试后台 设置数据到model中。
创建com.itheima.controller.TestController,代码如下:
@Controller
@RequestMapping("/test")
public class TestController {/**** 访问/test/hello 跳转到demo1页面* @param model* @return*/@RequestMapping("/hello")public String hello(Model model){model.addAttribute("hello","hello welcome");return "demo1";}
}
(5)测试
创建启动类com.itheima.ThymeleafApplication
,代码如下:
@SpringBootApplication
public class ThymeleafApplication {public static void main(String[] args) {SpringApplication.run(ThymeleafApplication.class,args);}
}
启动系统,并在浏览器访问
http://localhost:8080/test/hello
3 Thymeleaf基本语法
(1)th:action
定义后台控制器路径,类似<form>
标签的action属性。
例如:
<form id="login-form" th:action="@{/test/hello}"><button>提交</button>
</form>
表示提交的请求地址为/test/hello
(2)th:each
对象遍历,功能类似jstl中的<c:forEach>
标签。
创建com.itheima.model.User,代码如下:
public class User {private Integer id;private String name;private String address;//..get..set
}
Controller添加数据
/**** 访问/test/hello 跳转到demo1页面* @param model* @return*/
@RequestMapping("/hello")
public String hello(Model model){model.addAttribute("hello","hello welcome");//集合数据List<User> users = new ArrayList<User>();users.add(new User(1,"张三","深圳"));users.add(new User(2,"李四","北京"));users.add(new User(3,"王五","武汉"));model.addAttribute("users",users);return "demo1";
}
页面输出
<table><tr><td>下标</td><td>编号</td><td>姓名</td><td>住址</td></tr><tr th:each="user,userStat:${users}"><td>下标:<span th:text="${userStat.index}"></span>,</td><td th:text="${user.id}"></td><td th:text="${user.name}"></td><td th:text="${user.address}"></td></tr>
</table>
测试效果
(3)Map输出
后台添加Map
//Map定义
Map<String,Object> dataMap = new HashMap<String,Object>();
dataMap.put("No","123");
dataMap.put("address","深圳");
model.addAttribute("dataMap",dataMap);
页面输出
<div th:each="map,mapStat:${dataMap}"><div th:text="${map}"></div>key:<span th:text="${mapStat.current.key}"></span><br/>value:<span th:text="${mapStat.current.value}"></span><br/>==============================================
</div>
测试效果
(4)数组输出
后台添加数组
//存储一个数组
String[] names = {"张三","李四","王五"};
model.addAttribute("names",names);
页面输出
<div th:each="nm,nmStat:${names}"><span th:text="${nmStat.count}"></span><span th:text="${nm}"></span>==============================================
</div>
测试效果
(5)Date输出
后台添加日期
//日期
model.addAttribute("now",new Date());
页面输出
<div><span th:text="${#dates.format(now,'yyyy-MM-dd hh:ss:mm')}"></span>
</div>
测试效果
(6)th:if条件
后台添加年龄
//if条件
model.addAttribute("age",22);
页面输出
<div><span th:if="${(age>=18)}">终于长大了!</span>
</div>
测试效果
(7)使用javascript
java代码为:
(8) 字符拼接 使用||
后台代码:
模板:
4 搜索页面渲染
4.1 搜索分析
搜索页面要显示的内容主要分为3块。
1)搜索的数据结果
2)筛选出的数据搜索条件
3)用户已经勾选的数据条件
4.2 搜索实现
搜索的业务流程如上图,用户每次搜索的时候,先经过搜索业务工程,搜索业务工程调用搜索微服务工程,这里搜索业务工程单独挪出来的原因是它这里涉及到了模板渲染以及其他综合业务处理,以后很有可能会有移动端的搜索和PC端的搜索,后端渲染如果直接在搜索微服务中进行,会对微服务造成一定的侵入,不推荐这么做,推荐微服务独立,只提供服务,如果有其他页面渲染操作,可以搭建一个独立的消费工程调用微服务达到目的。
4.2.1 搜索工程搭建
(1)工程创建
在changgou-web工程中创建changgou-web-search工程,并在changgou-web的pom.xml中引入如下依赖:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--feign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
</dependencies>
(2)静态资源导入
将资源中的页面/前端页面/search.html
拷贝到工程的resources/templates
目录下,js、css等拷贝到static
目录下,如下图:
(3)Feign创建
修改changgou-service-search-api,添加com.changgou.search.feign.SkuFeign
,实现调用搜索,代码如下:
@FeignClient(name="search",path = "/search")
//@RequestMapping("/search") == path="/search"
public interface SkuFeign {@PostMappingpublic Map search(@RequestBody(required = false) Map<String, String> searchMap);
}
(4)changgou-web-search的pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>changgou-web</artifactId><groupId>com.changgou</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>changgou-web-search</artifactId><dependencies><!--search API依赖--><dependency><groupId>com.changgou</groupId><artifactId>changgou-service-search-api</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
</project>
(5)搜索调用
在changgou-web-search中创建com.changgou.search.controller.SkuController,实现调用搜索,代码如下:
@Controller
@RequestMapping(value = "/search")
public class SkuController {@Autowiredprivate SkuFeign skuFeign;/*** 搜索* @param searchMap* @return*/@GetMapping(value = "/list")public String search(@RequestParam(required = false) Map searchMap, Model model){//调用changgou-service-search微服务Map resultMap = skuFeign.search(searchMap);model.addAttribute("result",resultMap);return "search";}
}
(6)启动类创建
修改changgou-web-search,添加启动类com.changgou.SearchWebApplication,代码如下:
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = "com.changgou.search.feign")
public class SearchWebApplication {public static void main(String[] args) {SpringApplication.run(SearchWebApplication.class,args);}
}
(7)application.yml配置文件
server:port: 18088
eureka:client:service-url:defaultZone: http://127.0.0.1:7001/eurekainstance:prefer-ip-address: true
feign:hystrix:enabled: true
spring:thymeleaf:cache: falseapplication:name: search-webmain:allow-bean-definition-overriding: true
(8)项目完整结构
copy 静态资源到static下:并且修改路径:
将./ 改成 /
在search.html的头部引入thymeleaf标签
<html xmlns:th="http://www.thymeleaf.org">
测试:http://localhost:18088/search/list
,效果如下:
4.2.2 搜索数据填充
后端搜索到数据后,前端页面进行数据显示,显示的数据分为3部分
1)搜索的数据结果
2)筛选出的数据搜索条件
3)用户已经勾选的数据条件
4.2.3 关键字搜索
用户每次输入关键字的时候,直接根据关键字搜索,关键字搜索的数据会存储到result.rows
中,页面每次根据result获取rows,然后循环输出即可,同时页面的搜索框每次需要回显搜索的关键词。
实现思路
1.前端表单提交搜索的关键词
2.后端根据关键词进行搜索
3.将搜索条件存储到Model中
4.页面循环迭代输出数据
5.搜索表单回显搜索的关键词
(1)后台搜索实现
修改SkuController的search方法,代码如下:
/*** 搜索* @param searchMap* @return*/
@GetMapping(value = "/list")
public String search(@RequestParam(required = false) Map<String,String> searchMap, Model model){//调用changgou-service-search微服务Map<String,Object> resultMap = skuFeign.search(searchMap);//搜索数据结果model.addAttribute("result",resultMap);//搜索条件model.addAttribute("searchMap",searchMap);return "search";
}
(2)页面搜索实现
修改search.html
注意:搜索按钮为submit提交。
(3)页面结果输出
修改search.html,代码如下:
(4)测试
搜索华为
关键字,效果如下:
4.3 搜索条件回显
搜索条件除了关键字外,还有分类、品牌、以及规格,这些在我们前面已经将数据存入到了Map中,我们可以直接从Map中将数据取出,然后在页面输出即可。
分类:result.categoryList
品牌:result.brandList
规格:result.specList
修改search.html的条件显示部分,代码如下:
上图代码如下:
<!--selector-->
<div class="clearfix selector"><div class="type-wrap" th:if="${#maps.containsKey(result, 'categoryList')}"><div class="fl key">分类</div><div class="fl value"><span th:each="category,categoryStat:${result.categoryList}"><a th:text="${category}"></a> </span></div><div class="fl ext"></div></div><div class="type-wrap logo" th:if="${#maps.containsKey(result, 'brandList')}"><div class="fl key brand">品牌</div><div class="value logos"><ul class="logo-list"><li th:each="brand,brandStat:${result.brandList}"><a th:text="${brand}"></a></li></ul></div><div class="ext"><a href="javascript:void(0);" class="sui-btn">多选</a><a href="javascript:void(0);">更多</a></div></div><div class="type-wrap" th:each="spec,specStat:${result.specList}" th:unless="${#maps.containsKey(searchMap, 'spec_'+spec.key)}"><div class="fl key" th:text="${spec.key}"></div><div class="fl value"><ul class="type-list"><li th:each="op,opStat:${spec.value}"><a th:text="${op}"></a></li></ul></div><div class="fl ext"></div></div><div class="type-wrap" th:unless="${#maps.containsKey(searchMap, 'price')}"><div class="fl key">价格</div><div class="fl value"><ul class="type-list"><li><a th:text="0-500元"></a></li><li><a th:text="500-1000元"></a></li><li><a th:text="1000-1500元"></a></li><li><a th:text="1500-2000元"></a></li><li><a th:text="2000-3000元"></a></li><li><a th:text="3000元以上"></a></li></ul></div><div class="fl ext"></div></div><div class="type-wrap"><div class="fl key">更多筛选项</div><div class="fl value"><ul class="type-list"><li><a>特点</a></li><li><a>系统</a></li><li><a>手机内存 </a></li><li><a>单卡双卡</a></li><li><a>其他</a></li></ul></div><div class="fl ext"></div></div>
</div>
解释:
th:unless:条件不满足时,才显示
${#maps.containsKey(result,'brandList')}:map中包含某个key
4.4 条件搜索实现
用户每次点击搜索的时候,其实在上次搜索的基础之上加上了新的搜索条件,也就是在上一次请求的URL后面追加了新的搜索条件,我们可以在后台每次拼接组装出上次搜索的URL,然后每次将URL存入到Model中,页面每次点击不同条件的时候,从Model中取出上次请求的URL,然后再加上新点击的条件参数实现跳转即可。
(1)后台记录搜索URL
修改SkuController,添加组装URL的方法,并将组装好的URL存储起来,代码如下:
(2)页面搜索对接
th:href 这里是超链接的语法,例如:th:href="@{${url}(price='500-1000')}"
表示请求地址是取url
参数的值,同时向后台传递参数price的值为500-100元。
4.5 移除搜索条件
如上图,用户点击条件搜索后,要将选中的条件显示出来,并提供移除条件的x
按钮,显示条件我们可以从searchMap中获取,移除其实就是将之前的请求地址中的指定条件删除即可。
(1)条件显示
修改search.html,代码如下:
解释:
${#strings.startsWith(sm.key,'spec_')}:表示以spec_开始的key
${#strings.replace(sm.key,'spec_','')}:表示将sm.key中的spec_替换成空
(2)移除搜素条件
修改search.html,移除分类、品牌、价格、规格搜索条件,代码如下:
4.6 排序
上图代码是排序代码,需要2个属性,sortRule
:排序规则,ASC或者DESC,sortField
:排序的域,前端每次只需要将这2个域的值传入到后台即可实现排序。
(1)后台组装排序URL
每次排序的时候恢复第1页查询,所以url地址我们需要重新拼接,每次切换排序的时候,不需要之前的排序信息,修改SkuController,代码如下:
代码如下:
private String url(Map<String, String> searchMap) {// { spec_网络:"移动4G","keywords":"华为"}String url = "/search/list"; // a/b?id=1&if (searchMap != null) {url += "?";for (Map.Entry<String, String> stringStringEntry : searchMap.entrySet()) {//如果是排序 则 跳过 拼接排序的地址 因为有数据if(stringStringEntry.getKey().equals("sortField") || stringStringEntry.getKey().equals("sortRule")){continue;}url += stringStringEntry.getKey() + "=" + stringStringEntry.getValue() + "&";}if(url.lastIndexOf("&")!=-1)url = url.substring(0, url.lastIndexOf("&"));}return url;
}
(2)前端排序实现
修改search.html,实现排序,代码如下:
这一块我们实现了价格排序
4.7 分页
真实的分页应该像百度那样,如下图:
(1)分页工具类定义
在comm工程中添加Page分页对象,代码如下:
public class Page <T> implements Serializable{// 页数(第几页)private long currentpage;// 查询数据库里面对应的数据有多少条private long total;// 从数据库查处的总记录数// 每页查5条private int size;// 下页private int next;private List<T> list;// 最后一页private int last;private int lpage;private int rpage;//从哪条开始查private long start;//全局偏移量public int offsize = 2;public Page() {super();}/****** @param currentpage* @param total* @param pagesize*/public void setCurrentpage(long currentpage,long total,long pagesize) {//可以整除的情况下long pagecount = total/pagesize;//如果整除表示正好分N页,如果不能整除在N页的基础上+1页int totalPages = (int) (total%pagesize==0? total/pagesize : (total/pagesize)+1);//总页数this.last = totalPages;//判断当前页是否越界,如果越界,我们就查最后一页if(currentpage>totalPages){this.currentpage = totalPages;}else{this.currentpage=currentpage;}//计算startthis.start = (this.currentpage-1)*pagesize;}//上一页public long getUpper() {return currentpage>1? currentpage-1: currentpage;}//总共有多少页,即末页public void setLast(int last) {this.last = (int) (total%size==0? total/size : (total/size)+1);}/***** 带有偏移量设置的分页* @param total* @param currentpage* @param pagesize* @param offsize*/public Page(long total,int currentpage,int pagesize,int offsize) {this.offsize = offsize;initPage(total, currentpage, pagesize);}/****** @param total 总记录数* @param currentpage 当前页* @param pagesize 每页显示多少条*/public Page(long total,int currentpage,int pagesize) {initPage(total,currentpage,pagesize);}/***** 初始化分页* @param total* @param currentpage* @param pagesize*/public void initPage(long total,int currentpage,int pagesize){//总记录数this.total = total;//每页显示多少条this.size=pagesize;//计算当前页和数据库查询起始值以及总页数setCurrentpage(currentpage, total, pagesize);//分页计算int leftcount =this.offsize, //需要向上一页执行多少次rightcount =this.offsize;//起点页this.lpage =currentpage;//结束页this.rpage =currentpage;//2点判断this.lpage = currentpage-leftcount; //正常情况下的起点this.rpage = currentpage+rightcount; //正常情况下的终点//页差=总页数和结束页的差int topdiv = this.last-rpage; //判断是否大于最大页数/**** 起点页* 1、页差<0 起点页=起点页+页差值* 2、页差>=0 起点和终点判断*/this.lpage=topdiv<0? this.lpage+topdiv:this.lpage;/**** 结束页* 1、起点页<=0 结束页=|起点页|+1* 2、起点页>0 结束页*/this.rpage=this.lpage<=0? this.rpage+(this.lpage*-1)+1: this.rpage;/**** 当起点页<=0 让起点页为第一页* 否则不管*/this.lpage=this.lpage<=0? 1:this.lpage;/**** 如果结束页>总页数 结束页=总页数* 否则不管*/this.rpage=this.rpage>last? this.last:this.rpage;}public long getNext() {return currentpage<last? currentpage+1: last;}public void setNext(int next) {this.next = next;}public long getCurrentpage() {return currentpage;}public long getTotal() {return total;}public void setTotal(long total) {this.total = total;}public long getSize() {return size;}public void setSize(int size) {this.size = size;}public long getLast() {return last;}public long getLpage() {return lpage;}public void setLpage(int lpage) {this.lpage = lpage;}public long getRpage() {return rpage;}public void setRpage(int rpage) {this.rpage = rpage;}public long getStart() {return start;}public void setStart(long start) {this.start = start;}public void setCurrentpage(long currentpage) {this.currentpage = currentpage;}/*** @return the list*/public List<T> getList() {return list;}/*** @param list the list to set*/public void setList(List<T> list) {this.list = list;}
}
(2)分页实现
由于这里需要获取分页信息,我们可以在changgou-service-search
服务中修改搜索方法实现获取分页数据,修改com.changgou.search.service.impl.SkuServiceImpl
的search方法,在return之前添加如下方法获取份额与数据:
//分页数据保存
//设置当前页码
resultMap.put("pageNum", pageNum);
resultMap.put("pageSize", 30);
修改SkuController,实现分页信息封装,代码如下:
(3)页面分页实现
修改search.html,实现分页查询,代码如下:
注意:每次如果搜条件发生变化都要从第1页查询,而点击下一页的时候,分页数据在页面给出,不需要在后台拼接的url中给出,所以在拼接url的时候,需要过滤掉分页参数,修改changgou-web-search
的控制层com.changgou.search.controller.SkuController
的url拼接方法,代码如下:
5.畅购商品详情页
5.1 需求分析
当系统审核完成商品,需要将商品详情页进行展示,那么采用静态页面生成的方式生成,并部署到高性能的web服务器中进行访问是比较合适的。所以,开发流程如下图所示:
执行步骤解释:
- 系统管理员(商家运维人员)修改或者审核商品的时候,会触发canal监控数据
- canal微服务获取修改数据后,调用静态页微服务的方法进行生成静态页
- 静态页微服务只负责使用thymeleaf的模板技术生成静态页
5.2 商品静态化微服务创建
5.2.1 需求分析
该微服务只用于生成商品静态页,不做其他事情。
5.2.2 搭建项目
(1)在changgou-web下创建一个名称为changgou-web-item的模块,如图:
(2)changgou-web-item中添加起步依赖,如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>changgou-web</artifactId><groupId>com.changgou</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>changgou-web-item</artifactId><dependencies><!--api 模块--><dependency><groupId>com.changgou</groupId><artifactId>changgou-service-goods-api</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
</project>
(3)修改application.yml的配置
server:port: 18085
eureka:client:service-url:defaultZone: http://127.0.0.1:7001/eurekainstance:prefer-ip-address: true
feign:hystrix:enabled: true
spring:thymeleaf:cache: falseapplication:name: itemmain:allow-bean-definition-overriding: true#rabbitmq:# host: 192.168.25.138
# 生成静态页的位置
pagepath: D:/project/workspace_changgou/changgou/changgou-parent/changgou-web/changgou-web-item/src/main/resources/templates/items
(4)创建系统启动类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = "com.changgou.goods.feign")
public class ItemApplication {public static void main(String[] args) {SpringApplication.run(ItemApplication.class,args);}
}
5.3 生成静态页
5.3.1 需求分析
页面发送请求,传递要生成的静态页的的商品的SpuID.后台controller 接收请求,调用thyemleaf的原生API生成商品静态页。
上图是要生成的商品详情页,从图片上可以看出需要查询SPU的3个分类作为面包屑显示,同时还需要查询SKU和SPU信息。
5.3.2 Feign创建
一会儿需要查询SPU和SKU以及Category,所以我们需要先创建Feign,修改changgou-service-goods-api,添加CategoryFeign,并在CategoryFeign中添加根据ID查询分类数据,代码如下:
/*** 获取分类的对象信息* @param id* @return*/
@GetMapping("/{id}")
public Result<Category> findById(@PathVariable(name = "id") Integer id);
在changgou-service-goods-api,添加SkuFeign,并添加根据SpuID查询Sku集合,代码如下:
/*** 根据条件搜索* @param sku* @return*/
@PostMapping(value = "/search" )
public Result<List<Sku>> findList(@RequestBody(required = false) Sku sku);
在changgou-service-goods-api,添加SpuFeign,并添加根据SpuID查询Spu信息,代码如下:
/**** 根据SpuID查询Spu信息* @param id* @return*/
@GetMapping("/{id}")
public Result<Spu> findById(@PathVariable(name = "id") Long id);
5.3.3 静态页生成代码
(1)创建Controller
在changgou-web-item中创建com.changgou.item.controller.PageController用于接收请求,测试生成静态页
@RestController
@RequestMapping("/page")
public class PageController {@Autowiredprivate PageService pageService;/*** 生成静态页面* @param id* @return*/@RequestMapping("/createHtml/{id}")public Result createHtml(@PathVariable(name="id") Long id){pageService.createPageHtml(id);return new Result(true, StatusCode.OK,"ok");}
}
(2)创建service
接口:
public interface PageService {/*** 根据商品的ID 生成静态页* @param spuId*/public void createPageHtml(Long spuId) ;
}
实现类:
上图代码如下:
@Service
public class PageServiceImpl implements PageService {@Autowiredprivate SpuFeign spuFeign;@Autowiredprivate CategoryFeign categoryFeign;@Autowiredprivate SkuFeign skuFeign;@Autowiredprivate TemplateEngine templateEngine;//生成静态文件路径@Value("${pagepath}")private String pagepath;/*** 构建数据模型* @param spuId* @return*/private Map<String,Object> buildDataModel(Long spuId){//构建数据模型Map<String,Object> dataMap = new HashMap<>();//获取spu 和SKU列表Result<Spu> result = spuFeign.findById(spuId);Spu spu = result.getData();//获取分类信息dataMap.put("category1",categoryFeign.findById(spu.getCategory1Id()).getData());dataMap.put("category2",categoryFeign.findById(spu.getCategory2Id()).getData());dataMap.put("category3",categoryFeign.findById(spu.getCategory3Id()).getData());if(spu.getImages()!=null) {dataMap.put("imageList", spu.getImages().split(","));}dataMap.put("specificationList",JSON.parseObject(spu.getSpecItems(),Map.class));dataMap.put("spu",spu);//根据spuId查询Sku集合Sku skuCondition = new Sku();skuCondition.setSpuId(spu.getId());Result<List<Sku>> resultSku = skuFeign.findList(skuCondition);dataMap.put("skuList",resultSku.getData());return dataMap;}/**** 生成静态页* @param spuId*/@Overridepublic void createPageHtml(Long spuId) {// 1.上下文Context context = new Context();Map<String, Object> dataModel = buildDataModel(spuId);context.setVariables(dataModel);// 2.准备文件File dir = new File(pagepath);if (!dir.exists()) {dir.mkdirs();}File dest = new File(dir, spuId + ".html");// 3.生成页面try (PrintWriter writer = new PrintWriter(dest, "UTF-8")) {templateEngine.process("item", context, writer);} catch (Exception e) {e.printStackTrace();}}
}
5.2.4 模板填充
(1)面包屑数据
修改item.html,填充三个分类数据作为面包屑,代码如下:
(2)商品图片
修改item.html,将商品图片信息输出,在真实工作中需要做空判断,代码如下:
(3)规格输出
(4)默认SKU显示
静态页生成后,需要显示默认的Sku,我们这里默认显示第1个Sku即可,这里可以结合着Vue一起实现。可以先定义一个集合,再定义一个spec和sku,用来存储当前选中的Sku信息和Sku的规格,代码如下:
页面显示默认的Sku信息
(5)记录选中的Sku
在当前Spu的所有Sku中spec值是唯一的,我们可以根据spec来判断用户选中的是哪个Sku,我们可以在Vue中添加代码来实现,代码如下:
添加规格点击事件
(6)样式切换
点击不同规格后,实现样式选中,我们可以根据每个规格判断该规格是否在当前选中的Sku规格中,如果在,则返回true添加selected样式,否则返回false不添加selected样式。
Vue添加代码:
页面添加样式绑定,代码如下:
5.2.5 静态资源过滤
生成的静态页我们可以先放到changgou-web-item工程中,后面项目实战的时候可以挪出来放到Nginx指定发布目录。一会儿我们将生成的静态页放到resources/templates/items目录下,所以请求该目录下的静态页需要直接到该目录查找即可。
我们创建一个EnableMvcConfig类,开启静态资源过滤,代码如下:
@ControllerAdvice
@Configuration
public class EnableMvcConfig implements WebMvcConfigurer{/**** 静态资源放行* @param registry*/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/items/**").addResourceLocations("classpath:/templates/items/");}
}
5.4.6 启动测试
启动eurekea服务端
启动商品微服务
启动静态化微服务 changgou-web-item
将静态资源导入到changgou-web-item中,如下图:
生成静态页地址 http://localhost:18085/page/createHtml/1087918019151269888
静态页生成后访问地址 http://localhost:18085/items/1087918019151269888.html
6 canal监听生成静态页
如上图详情页的解决方案. 监听到数据的变化,直接调用feign 生成静态页即可.
6.1 需求分析
当商品微服务审核商品之后,应当发送消息,这里采用了Canal监控数据变化,数据变化后,调用feign实现生成静态页
6.2 Feign创建
在changgou-service-api中创建changgou-web-item-api,该工程中主要创建changgou-web-item的对外依赖抽取信息。
(1)Feign创建
在changgou-web-item-api中创建com.changgou.item.feign.PageFeign,代码如下:
@FeignClient(name="item")
@RequestMapping("/page")
public interface PageFeign {/**** 根据SpuID生成静态页* @param id* @return*/@RequestMapping("/createHtml/{id}")Result createHtml(@PathVariable(name="id") Long id);
}
(2)pom.xml依赖
修改changgou-service-canal工程的pom.xml,引入如下依赖:
<!--静态页API 服务-->
<dependency><groupId>com.changgou</groupId><artifactId>changgou-web-item-api</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
(3)修改changgou-service-canal工程中的启动类
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient
@EnableCanalClient // 启用canal
@EnableFeignClients(basePackages = {"com.changgou.content.feign","com.changgou.item.feign"})
public class CanalApplication {public static void main(String[] args) {SpringApplication.run(CanalApplication.class, args);}
}
6.3 canal监听数据变化
监听类中,监听商品数据库的tb_spu的数据变化,当数据变化的时候生成静态页或者删除静态页
在原来的监听类中添加如下代码即可,
@Autowired
private PageFeign pageFeign;@ListenPoint(destination = "example",schema = "changgou_goods",table = {"tb_spu"},eventType = {CanalEntry.EventType.UPDATE, CanalEntry.EventType.INSERT, CanalEntry.EventType.DELETE})
public void onEventCustomSpu(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {//判断操作类型if (eventType == CanalEntry.EventType.DELETE) {String spuId = "";List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();for (CanalEntry.Column column : beforeColumnsList) {if (column.getName().equals("id")) {spuId = column.getValue();//spuidbreak;}}//todo 删除静态页}else{//新增 或者 更新List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();String spuId = "";for (CanalEntry.Column column : afterColumnsList) {if (column.getName().equals("id")) {spuId = column.getValue();break;}}//更新 生成静态页pageFeign.createHtml(Long.valueOf(spuId));}
}
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- Java输入输出流与文件管理
1.InputStream和OutputStream流类 这两类是Java语言中处理以位(bit)为单位的流,可处理二进制文件的数据,也可处理文本文件。虽然字节流可以操作文但是不提倡,因为用字节流操作文本文件,如果文件中有汉字&a…...
2024/4/14 16:57:31 - C/C++标准库之numeric
<numeric>是C标准程序库中的一个头文件,定义了C STL标准中的基础性的数值算法,函数并不多,一共5个,偶有接触,这里一并介绍一下,免得每次网上翻阅查找。 这五个函数分别为:accumulate&…...
2024/4/14 16:57:16 - 程序设计与算法(二):1. 枚举
目录 例 完美立方 例 生理周期 例 称硬币 练习 剑指 Offer 57 - II. 和为s的连续正数序列 练习 找出三位偶数 练习 1291. 顺次数 例子源于慕课课程:程序设计与算法二 例 完美立方 输入正整数N,N以内满足 a^3b^3c^3d^3 ;需要…...
2024/4/17 22:25:26 - 设计模式——适配器
GitHub - bailuoxi66/designMode 参考:【狂神说Java】通俗易懂的23种设计模式教学(停更)_哔哩哔哩_bilibili 1. 适配器【可以更好的建模】 首先:有网线 //要被适配的类 网线 public class Adaptee {public void request(){Sys…...
2024/4/14 16:57:16 - Elasticsearch系列——kibana安装、elasticsearch-head安装、es安装插件、倒排索引、索引操作(数据库)、映射管理(类型)(表)、文档基本增删查、文档查询、模糊查询
文章目录昨日回顾1 kibana安装(postman)2 elasticsearch-head安装3 es安装官方,第三方插件3 倒排索引4 索引操作(数据库)5 映射管理(类型)(表)6 文档基本增删查改(一行一行数据&…...
2024/4/14 16:57:21 - sql表与索引操作
文章目录表的创建、修改与删除表的创建直接创建表从另一张表复制其表结构来创建表从另一张表的查询结果来创建表表的修改表的删除表的索引的创建、删除索引的创建索引的删除表的创建、修改与删除 表的创建 直接创建表 CREATE TABLE [IF NOT EXISTS] tb_name -- 不存在才创建…...
2024/4/20 13:35:14 - 【eNSP 华为模拟器】三层交换技术及操作步骤【图文】
三层交换技术一.三层交换技术二.实验1.实验要求2.实验拓扑3.实验配置三.总结一.三层交换技术 三层交换技术就是:二层交换技术三层转发技术。它解决了局域网中网段划分之后,网段中子网必须依赖路由器进行管理的局面,解决了传统路由器低速、复…...
2024/4/16 6:39:07 - Linux 配置单机 minio 服务
为了在 gitlab-runner 中使用 cache,配置了一个 minio 服务用于存储缓存的中间文件。 参考官方文档 下载 minio 服务端配置 /etc/default/minio 配置文件# 修改存储数据的路径 MINIO_VOLUMES"/tmp/minio/" # Use if you want to run MinIO on a custom …...
2024/4/7 4:22:19 - 英语3500词(五)Who is Your Favorite Athlete (2022.1.17)
athlete 1 n. 运动员,擅长运动的人 athletic 1 adj. 体育运动的,健壮的 用法搭配 an athletic man 健壮的男子sports meeting athletic meeting 运动会athletic sports 体育运动 词汇拓展 athletics n. 体育运动,体育竞技 amateur 1 …...
2024/4/18 5:32:44 - 《亿级流量网站架构核心技术》总结
目录 一、高可用 二、高并发 三、京东商品详情页示例 四、参考资料 一、高可用 二、高并发 三、京东商品详情页示例 四、参考资料 Hystrix实现线程隔离_爱我所爱0505-CSDN博客_hystrix线程隔离 Servlet3实现业务隔离(异步上下文)_爱我所爱0505-CSDN博客 应用级限流 — G…...
2024/4/14 16:57:16 - synchronized使用与原理
synchronized内置锁是一种对象锁(锁的是对象而非引用),作用粒度是对 象,可以用来实现对临界资源的同步互斥访问,是可重入的。 加锁的方式: 同步实例方法,锁是当前实例对象 同步类方法,锁是当前类对象 同步…...
2024/4/5 5:12:59 - C语言基础知识概览
文章目录1.什么是C语言2.第一个C语言程序3.数据类型4.变量,常量4.1定义变量的方法4.2变量的分类4.3变量的使用4.4变量的作用域和生命周期4.5常量5.字符串转义字符注释5.1 字符串5.2 转义字符5.3 注释6.选择语句7.循环语句8.函数9.数组9.1 数组定义9.2 数组的下标9.3…...
2024/4/20 16:53:28 - OCP开闭原则
设计模式六大原则之–开闭原则(OCP)...
2024/4/14 16:57:21 - Java单元测试之JUnit 5快速上手
单元测试是软件开发中必不可少的一环,但是在平常开发中往往因为项目周期紧,工作量大而被选择忽略,这样往往导致软件问题层出不穷。 线上出现的不少问题其实在有单元测试的情况下就可以及时发现和处理,因此培养自己在日常开发中写…...
2024/4/14 16:58:07 - Day-5-常用API 异常机制
一 BigInteger 1、Integer类作为int的包装类,能存储的最大整型值为231-1,Long类也是有限的, 最大为263-1。如果要表示再大的整数,不管是基本数据类型还是他们的包装类 都无能为力,更不用说进行运算了。 2、j…...
2024/4/14 16:58:07 - 计算机网络-无线网络和移动网络
无线网络和移动网络 在电话技术领域,蜂窝电话的数量比地球上的人口还要多。蜂窝电话的优点是显而易见的,通过一个移动性强、重量轻的设备,能够在任何地方、任何时间无缝地接入全球电话网络、而如今的智能手机、平板电脑等能够以无线的方式经…...
2024/4/14 16:58:07 - 想学软件测试福利来了,最全资料包,免费大放送
软件测试零基础如何入门? 在职测试如何快速进阶为测试开发? 学历不行怎样才能内推进入一线名企大厂?...... 这里给你答案! 200G软件测试教程资料,100名企大厂内推资源 点击下方名片,免费获取领取方式&…...
2024/4/18 13:31:15 - HCIP笔记
不同类型的LSA之间的比较 域内和域间——域内路由(通过1类、2类LSA学习到的路由)优先级高于域间路由(通过3类LSA学到的路由)优先级2、域间和域外——域间路由优先级高于域外路由(通过5类,7类LSA学到的路由…...
2024/4/23 7:27:10 - 人是否可以讲粗话
人要表达自己的情绪,有时候就要用那种单刀直入的、痛痛快快的、活活泼泼的语言来表达。小罗斯福He may be a son of bitch, but hes our son of bitch杜鲁门And I told Bradley,"The son of bitch isnt going to resign on me, I want him fired."克林顿绯…...
2024/4/19 19:41:11 - Fabric 各种配置文件梳理
1.core.yaml : Peer节点的示例配置文件,有六个部分(会随版本变化略加改动) 日志部分:指定模块日志级别peer部分:Peer服务核心配置内容vm部分:配置链码运行的环境,比如Docker容器链码部分&#…...
2024/4/20 2:54:32
最新文章
- ky10升级内核版本
1、创建离线内核包 登录一个可以连接外网的ky10虚机,执行如下操作: mkdir kernel-4.19.90-52.36.v2207.ky10 yum install --downloadonly --downloaddir/root/kernel-4.19.90-52.36.v2207.ky10/ kernel* tar -zcvf kernel-4.19.90-52.36.v2207.ky10-…...
2024/4/25 18:00:27 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - FreeRTOS学习 -- 再识
工作中一直使用FreeRTOS进行着开发,但是没有进行过系统的总结过。现在将快速使用几天时间将FreeRTOS相关知识点加以总结。 官网: https://www.freertos.org/zh-cn-cmn-s/ 参看资料: 正点原子 STM32F1 FreeRTOS开发手册_V1.2.pdf The FreeRTOS…...
2024/4/23 6:24:52 - 流域生态系统水-碳-氮耦合过程模拟
流域是一个相对独立的自然地理单元,它是以水系为纽带,将系统内各自然地理要素连结成一个不可分割的整体。碳和氮是陆地生态系统中最重要的两种化学元素,而在流域系统内,水-碳-氮是相互联动、不可分割的耦合体。随着流域内人类活动…...
2024/4/23 6:21:35 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/4/25 11:51:20 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/4/23 13:30:22 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/23 13:28:06 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/4/24 18:16:28 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/23 13:27:44 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/19 11:57:53 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/23 13:29:53 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/25 16:48:44 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/25 13:39:44 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/4/23 22:01:21 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/23 13:29:23 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/25 0:00:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/25 4:19:21 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/19 11:59:23 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/4/19 11:59:44 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/4/25 2:10:52 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/24 16:38:05 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/25 13:19:01 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/4/23 13:27:51 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/23 13:27:19 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57