B072-项目实战-用户模块--前台登录 三方登录

目录

      • 前台登录-账号登录
        • 前端完成
        • 左上角显示用户信息
        • 配置前置拦截器、后置拦截器和不受限资源拦截器
      • 三方登录-微信登录
        • 概述
        • 流程图
        • 用法
        • 代码实现步骤分析:
        • 实现准备
        • 代码
          • 前端
            • login.html
            • callback.html
          • 后端
            • LoginController-微信登录
            • LoginServiceImpl-微信登录
            • 解决回调域名不能跨域
            • 绑定页面准备
            • 改造发短信验证码接口
            • LoginController-绑定微信用户
            • LoginServiceImpl-绑定微信用户

前台登录-账号登录

前端完成

1)后台登录接口(和管理员登录接口共用,以type划分)
2)前台登录实现并且保存loginInfo和token到localStorage,登录成功跳转首页,并展示用户名
3)前台通过axios的前置拦截器携带token到后台
4)后台做token的登录拦截器,如果没有回报错给前台(前面已写,共用)
5)前台通过axios后置拦截器对后台登录拦截错误进行跳转到登录页面
6)前台也要做拦截-有的地址是不需要访问后台

login.html中引入axios和vue
标签 - data - 按钮 - methods

localstorage与域名挂钩,同一个域名下的key只能存在一个,不同域名下的key名称可以一样,即前后台的token名称可以一样

login.html

<html>
<head lang="en"><meta charset="UTF-8"><title>登录</title><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport"content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"><meta name="format-detection" content="telephone=no"><meta name="renderer" content="webkit"><meta http-equiv="Cache-Control" content="no-siteapp"/><link rel="stylesheet" href="./AmazeUI-2.4.2/assets/css/amazeui.css"/><link href="./css/dlstyle.css" rel="stylesheet" type="text/css"><!--引入vue和axios--><script src="js/plugin/vue/dist/vue.min.js"></script><script src="js/plugin/axios/dist/axios.js"></script><!--全局使用--><script src="js/common.js"></script>
</head>
<body>
<div class="login-boxtitle"><a href="home.html"><img alt="logo" src="./images/logobig.png"/></a>
</div>
<div class="login-banner"><div class="login-main"><div class="login-banner-bg"><span></span><img src="./images/big.jpg"/></div><div class="login-box"><h3 class="title">登录商城</h3><div class="clear"></div><div class="login-form"><form><div class="user-name"><label for="user"><i class="am-icon-user"></i></label><input type="text" name="" v-model="userLoginForm.username" id="user" placeholder="邮箱/手机/用户名"></div><div class="user-pass"><label for="password"><i class="am-icon-lock"></i></label><input type="password" name="" v-model="userLoginForm.password" id="password"placeholder="请输入密码"></div></form></div><div class="login-links"><label for="remember-me"><input id="remember-me" type="checkbox">记住密码</label><a href="#" class="am-fr">忘记密码</a><a href="register.html" class="zcnext am-fr am-btn-default">注册</a><br/></div><div class="am-cf"><input type="button" @click="login" name="" value="登 录" class="am-btn am-btn-primary am-btn-sm"></div><div class="partner"><h3>合作账号</h3><div class="am-btn-group"><li><a href="#"><i class="am-icon-qq am-icon-sm"></i><span>QQ登录</span></a></li><li><a href="#"><i class="am-icon-weibo am-icon-sm"></i><span>微博登录</span> </a></li><li><a href="#"><i class="am-icon-weixin am-icon-sm"></i><span>微信登录</span> </a></li></div></div></div></div>
</div>
<div class="footer "><div class="footer-hd "><p><a href="# ">恒望科技</a><b>|</b><a href="# ">商城首页</a><b>|</b><a href="# ">支付宝</a><b>|</b><a href="# ">物流</a></p></div><div class="footer-bd "><p><a href="# ">关于恒望</a><a href="# ">合作伙伴</a><a href="# ">联系我们</a><a href="# ">网站地图</a><em>© 2015-2025 Hengwang.com 版权所有. 更多模板 <a href="http://www.cssmoban.com/" target="_blank"title="模板之家">模板之家</a> - Collect from <ahref="http://www.cssmoban.com/" title="网页模板" target="_blank">网页模板</a></em></p></div>
</div>
</body>
<script type="text/javascript">new Vue({el: ".login-main",data: {userLoginForm: {username: "",password: "",type: 1}},methods: {login() {this.$http.post("/login/account", this.userLoginForm).then(result => {result = result.data;if (result.success) {//保存信息到localstoragevar resultObj = result.resultObj;localStorage.setItem("token", resultObj.token);	//不同域名下的key名称可以一样localStorage.setItem("logininfo", JSON.stringify(resultObj.logininfo));alert("登录成功!");//提示登录成功//跳转到主页location.href = "/index.html";} else {alert(result.message);}}).catch(result => {alert("系统异常!");})}},mounted() {}})
</script>
</html>

左上角显示用户信息

index.html
引入vue和axios
页面元素 - vue实例 -

<!--引入vue和axios-->
<script src="js/plugin/vue/dist/vue.min.js"></script>
<script src="js/plugin/axios/dist/axios.js"></script>
<!--全局使用-->
<script src="js/common.js"></script>
<div id="myDiv">
	<div class="menu-hd" v-if="logininfo"><a href="#" target="_top" class="h">欢迎您:<span style="color: red">{{logininfo.username || logininfo.phone || logininfo.email ||''}}</span></a></div><div class="menu-hd" v-else><a href="#" target="_top" class="h">亲,请登录</a><a href="register.html" target="_blank">免费注册</a></div>
		<script type="text/javascript">new Vue({el:"#myDiv",data:{logininfo:null},mounted(){let loginObjStr =  localStorage.getItem("logininfo");if(loginObjStr){this.logininfo = JSON.parse(loginObjStr);}}})</script>

配置前置拦截器、后置拦截器和不受限资源拦截器

common.js

//配置axios的全局基本路径
/*axios.defaults.baseURL='/api' 前端解决跨域*/
axios.defaults.baseURL='http://localhost:8080/'/*** 使用前提,要发送axios的页面,都应该要引入common.js* axios前置拦截器:作用:每次发送axios请求,需要携带token给后端*/
axios.interceptors.request.use(config=>{//携带tokenlet uToken =  localStorage.getItem("token");if(uToken){config.headers['token']=uToken;}return config;//一定要返回配置
},error => {Promise.reject(error);
})/*** axios后置拦截:作用:后端ajax请求 报错,在这里处理*/
axios.interceptors.response.use(result=>{let data = result.data;if(!data.success && data.message==="noLogin"){localStorage.removeItem('token');localStorage.removeItem('logininfo');/*router.push({ path: '/login' });*/location.href = "/login.html";}return result;
},error => {Promise.reject(error);
})//全局属性配置,在任意组件内可以使用this.$http获取axios对象
Vue.prototype.$http = axios/*js拦截*/
let uri = location.href;//http://127.0.0.1/index.html
/*不是这两个结尾的请求地址,我应该阻止,并校验是否登录*/
if(uri.indexOf("/login.html") == -1 && uri.indexOf("/register.html")==-1&& uri.indexOf("/index.html") == -1){let loginObj = localStorage.getItem('logininfo');if(!loginObj){location.href = "/login.html";}
}

三方登录-微信登录

概述

用户通过微信登录链接访问微信平台
微信返回登录二维码
用户扫码进入微信平台
微信校验用户后返回链接+校验码给本平台 ------- 返回页面信息
本平台通过校验码去微信获取用户信息token ------- 解析页面信息绑定数据,通过校验码去微信获取用户信息token,通过token去微信拿用户信息保存到本平台,设置默认用户密码,下次再扫码校验是微信的和用户是存在的就登录成功

流程图

在这里插入图片描述
在这里插入图片描述

用法

https://open.weixin.qq.com/:注册为开发者
-> 网站应用开发 - 填写信息 - 邮箱激活 - 完善开发者资料 -
开发者认证 - 人工审核,自己无法申请成功,用源码提供的
APPID:wxd853562a0548a7d0,SECRET:4a5d5615f93f24bdba2ba8534642dbb6,回调域:bugtracker.itsource.cn

目前回调域名没有对外,我们是127.0.0.1,要让外网微信能访问到内网地址,
回调域相当于宠物平台的后端地址
开发阶段通过本地hosts解析将回调域名指向本机127.0.0.1

代码实现步骤分析:

在这里插入图片描述
在这里插入图片描述

微信扫码登录具体实现步骤:
1.用户点击主站微信登录A标签按钮,平台带上 appid 和 回调页面地址 发送请求到微信平台,
0.微信端会弹出二维码扫码界面给用户
1.用户扫码后,微信平台获得授权生成http://bugtracker.itsource.cn/callback.html?code=xxxxx,回调到平台callback页面
2.平台callback页面页面加载解析地址栏中的code,携带code和binder.html发送微信登录请求到后端,后端通过APPID,SECRET和code到微信平台获取token和授权用户唯一标识openid再根据openid看用户是否在本地是否存有WxUser信息和绑定用户User_id
如果有,通过绑定的User_id查询到登录信息,生成token和logininfo返回前端  --->免密登录3.如果没有,返回binderUrl+token+openId给前端,前端跳转到绑定页面,页面加载解析token和openId,填写手机号与短信验证码后带上token和openId发送绑定请求到后端,后端完成验证码验证后携带token和openid发送请求到微信平台拿用户微信信息然后根据手机号和类型看是否存在此平台登录用户,存在就查出user结合wxUserStr直接保存和绑定进wxUser表,--->然后免密登录
不存在就根据phone和type生成logininfo(密码默认)和拷贝user保存,然后user结合wxUserStr保存和绑定进wxUser表,--->然后免密登录tips:后面生成logininfo设置默认密码时可以发短信告知用户
项目中该怎么干?1.用户点击前端微信按钮2.web发起获取授权请求到微信,带上回调地址callback.html3.微信展示二维码给用户,让用户扫码4.用户扫码后,跳转到我们的callBack页面,会加上一个授权码code给到我们5.那么我们在mounted中可以发起微信登录请求到我们的pethome后台,传递一个绑定用户信息的地址过来6.后台接口中直接获取code,然后发起获取token的请求得到token我们是不是又可以发起获取微信用户信息的请求7.得到用户后,判断微信用户在我们系统中有没有对应的t_user如果有,实现免密登录如果没有,弹出一个绑定用户账号信息的窗口,让他完成信息绑定(相当于给他注册一个账号)然后在登录成功

实现准备

见文档

代码

前端
login.html
<li><a href="https://open.weixin.qq.com/connect/qrconnect?appid=wxd853562a0548a7d0&redirect_uri=http://bugtracker.itsource.cn/callback.html&response_type=code&scope=snsapi_login&state=1#wechat_redirect "><i class="am-icon-weixin am-icon-sm"></i><span>微信登录</span> </a></li>

拷贝callback页面到web根目录,修改vue和axios引入路径,js拦截放行callback页面,common.js下面补充parseUrlParams2Obj方法

callback.html
<html lang="en">
<head><meta charset="UTF-8"><title>回调</title><!--引入vue和axios--><script src="js/plugin/vue/dist/vue.min.js"></script><script src="js/plugin/axios/dist/axios.js"></script><!--全局使用--><script src="js/common.js"></script>
</head>
<body><div id="myDiv"></div>
<script type="text/javascript">new Vue({el:"#myDiv",mounted(){//解析参数上let url = location.href;let paramObj = parseUrlParams2Obj(url);let binderUrl="http://bugtracker.itsource.cn/binder.html";//封装请求参数let param = {"code":paramObj.code,"binderUrl":binderUrl};//发送微信登录验证  到pethome后端this.$http.post("/login/wechat",param).then(result=>{result = result.data;if(result.success){//已经绑定,免密登录成功alert("登录成功");//1.将token和登录信息存入localStoragelet {token,loginInfo} = result.resultObj;localStorage.setItem("token",token);localStorage.setItem("loginInfo",JSON.stringify(loginInfo));//2.跳转到首页,并显示登录信息location.href="index.html";}else{let url = result.resultObj;//没有绑定,跳转到绑定页面location.href=url;}}).catch(result=>{alert("系统异常!");})}})
</script>
</body>
</html>
后端
LoginController-微信登录
    /*** 微信扫码登录* @param params  code  binderUrl* @return*/@PostMapping("/wechat")public AjaxResult wechat(@RequestBody Map<String,String> params){try {return loginService.wechat(params);} catch (Exception e) {e.printStackTrace();return AjaxResult.me().setMessage("系统繁忙,稍后重试!");}}
LoginServiceImpl-微信登录
    /*** 空校验* 通过code去微信平台拿token  同时返回openid* 校验是否微信用户和我们平台yoghurt绑定* 如果绑定了, 直接免密登录成功* 如果没有绑定*   跳转到绑定用户信息页面?后端能跳转吗?json {success:false,binderUrl:....}*/@Overridepublic AjaxResult wechat(Map<String, String> params) {//1.获取参数String code = params.get("code");String binderUrl = params.get("binderUrl");if (StringUtils.isEmpty(code) || StringUtils.isEmpty(binderUrl)) {return AjaxResult.me().setMessage("必要参数为空,登录失败");}//2.发送http请求去微信平台拿tokenString accessTokenUrl = WxConstants.GET_ACK_URL.replace("APPID", WxConstants.APPID).replace("SECRET", WxConstants.SECRET).replace("CODE", code);String strObj = HttpClientUtils.httpGet(accessTokenUrl);System.out.println(strObj);JSONObject object = JSONObject.parseObject(strObj);String accessToken = (String) object.get("access_token");String openId = (String) object.get("openid");//3.判断是否绑定微信用户  通过openId 查询微信用户信息,如果查询到了并且有useridWxUser wxUser = wxUserMapper.loadByOpenId(openId);//  3.1 如果查询到值,并且绑定了数据,直接免密登录if (wxUser != null && wxUser.getUser_id() != null) {//免密登录// 2.1 如果密码相等  登录成功  存redis,封装返回值/*** 这里的redis  key就是前端需要存储的token*///通过用户ID查询到登录人Logininfo logininfo = logininfoMapper.loadbyUserId(wxUser.getUser_id());String token = UUID.randomUUID().toString();redisTemplate.opsForValue().set(token, logininfo, 30, TimeUnit.MINUTES);Map<String, Object> map = new HashMap<>();map.put("token", token);//作为一个高级技师 我们不能将账号和密码传给前端,应该过滤掉logininfo.setUsername(null);logininfo.setPassword(null);map.put("logininfo", logininfo);return AjaxResult.me().setResultObj(map);//免密登录成功返回} else {// 3.2 如果没有查询那么应该跳转到绑定页面String resultUrl = binderUrl + "?accessToken=" + accessToken + "&openId=" + openId;return AjaxResult.me().setSuccess(false).setResultObj(resultUrl);//免密登录成功返回}}
解决回调域名不能跨域

GlobalCorsConfig

config.addAllowedOrigin("http://bugtracker.itsource.cn");
config.addAllowedOrigin("http://bugtracker.itsource.cn:80");
绑定页面准备

拷贝binder.html到web根目录,调整引入路径,调整参数名,js拦截放行

改造发短信验证码接口

见代码

LoginController-绑定微信用户

在这里插入图片描述
在这里插入图片描述

    /*** 绑定微信用户接口*/@PostMapping("/binder/wechat")public AjaxResult binder(@RequestBody Map<String,String> params){try {return loginService.binder(params);} catch (Exception e) {e.printStackTrace();return AjaxResult.me().setMessage("系统繁忙,稍后重试!");}}
LoginServiceImpl-绑定微信用户
    @Overridepublic AjaxResult binder(Map<String, String> params) {String phone  = params.get("phone");String accessToken  = params.get("accessToken");String openId  = params.get("openId");String verifyCode  = params.get("verifyCode");//1.空校验if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(openId) || StringUtils.isEmpty(verifyCode)){return AjaxResult.me().setMessage("必要参数为空,绑定失败");}//2.验证码是否过期或正确Object codeObj = redisTemplate.opsForValue().get(UserConstant.USER_BINDING_CODE+":"+phone);//  2.1 验证码是否过期if(codeObj == null){return AjaxResult.me().setMessage("验证码已经过期,请重新发送验证码!");}String code = ((String)codeObj).split(":")[0];//  2.2 验证码是否正确if(!verifyCode.equalsIgnoreCase(code)){return AjaxResult.me().setMessage("请输入正确的验证码!");}//3.查询微信平台用户//发送http请求去微信平台拿微信用户String userUrl = WxConstants.GET_USER_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);String strObj = HttpClientUtils.httpGet(userUrl);System.out.println(strObj);if(strObj == null){//拿不到微信用户了return AjaxResult.me().setMessage("微信用户不存在!");}UserDto dto = new UserDto();dto.setPhone(phone);dto.setType(1);//4.查询平台用户是否存在Logininfo logininfo = logininfoMapper.loadByDto(dto);User user = null;if(logininfo != null){//存在平台用户,那么曾经这个手机号已经注册过,直接绑定就可以了user = userMapper.loadByloginInfoId(logininfo.getId());}else{//平台不存在手机相关的用户logininfo = createLoginInfo(phone);user = loginInfo2User(logininfo);logininfoMapper.save(logininfo);user.setInfo(logininfo);userMapper.save(user);}//5.绑定微信用户WxUser wxUser = user2WxUser(strObj, user);wxUserMapper.save(wxUser);//6.免密登录String token = UUID.randomUUID().toString();redisTemplate.opsForValue().set(token, logininfo, 30, TimeUnit.MINUTES);Map<String,Object> map = new HashMap<>();map.put("token", token);//作为一个高级技师 我们不能将账号和密码传给前端,应该过滤掉logininfo.setUsername(null);logininfo.setPassword(null);map.put("logininfo",logininfo);return AjaxResult.me().setResultObj(map);//免密登录成功返回}private WxUser user2WxUser(String wxUserStr, User user) {//装换微信用户信息JSONObject jsonObject = JSONObject.parseObject(wxUserStr);WxUser wxUser =  new WxUser();wxUser.setUser_id(user.getId());    // 绑定平台用户wxUser.setOpenid(jsonObject.getString("openid"));wxUser.setNickname(jsonObject.getString("nickname"));wxUser.setSex(jsonObject.getInteger("sex"));wxUser.setAddress(null);wxUser.setHeadimgurl(jsonObject.getString("headimgurl"));wxUser.setUnionid(jsonObject.getString("unionid"));return wxUser;}private User loginInfo2User(Logininfo info) {User user = new User();BeanUtils.copyProperties(info,user);//根据同名原则拷贝return user;}/*** 通过Phone创建info*/private Logininfo createLoginInfo(String phone) {Logininfo info = new Logininfo();info.setUsername(phone);info.setPhone(phone);//设置一个默认密码  todo:默认密码可以发短信告知用户String salt = StrUtils.getComplexRandomString(32);String md5Pwd = MD5Utils.encrypByMd5(StrUtils.getComplexRandomString(6) + salt);info.setType(1);//设置前端type值info.setSalt(salt);info.setPassword(md5Pwd);return info;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/3215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安达发|某大厂使用APS计划排程真实成功案例

在很多群里、朋友圈、公众号上可以看到&#xff0c;很多精益咨询老师认为&#xff0c;不仅ERP不啥用&#xff0c;APS更是无聊之举&#xff0c;而且肯定是用不好的。但&#xff0c;事实上可能还真不是这样的。 一个深圳的客户&#xff0c;用了APS以后&#xff0c;不仅装配的齐套…

桥梁监测需要哪些设备?

随着我国经济的发展&#xff0c;我国桥梁建设也迈上了新的台阶。截至2022年底&#xff0c;我国的公路桥梁总数达到了103.32万座。然而&#xff0c;随着在役桥梁使用时间的增长&#xff0c;承载能力受到荷载、环境以及结构退化等因素的影响&#xff0c;桥梁安全问题日益凸显。桥…

vue3和gin框架实现简单的断点续传

vue3和gin框架实现简单的断点续传 前端代码 Test.vue <template><div><inputtype"file"ref"uploadRef"change"upload"multiple/><templatev-for"item in fileList":key"item.key"><br><…

spring复习:(39)注解方式的ProxyFactoryBean

一、定义接口 package cn.edu.tju.study.service;public interface MyService {void myMethod(); }二、定义实现类&#xff1a; package cn.edu.tju.study.service;public class MyServiceImpl implements MyService{Overridepublic void myMethod() {System.out.println(&qu…

Redis 读写分离 使用redisTemplate执行lua脚本时,报错处理

项目框架说明 项目配置 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.4</version></parent>....<dependency><groupId>org.springfra…

(学习笔记-TCP基础知识)TCP与UDP区别

UDP UDP不提供复杂的控制机制&#xff0c;利用IP提供面向[无连接]的通信服务。 UDP协议非常简单&#xff0c;头部只有8个字节(位)&#xff0c;UDP的头部格式如下&#xff1a; 目标和源端口&#xff1a;主要是告诉UDP协议应该把报文发给哪个进程包长度&#xff1a;该字段保存了…

TinyKv流程梳理三

split流程 处理协程启动 func (bs *Raftstore) startWorkers(peers []*peer) {ctx : bs.ctxworkers : bs.workersrouter : bs.routerbs.wg.Add(2) // raftWorker, storeWorkerrw : newRaftWorker(ctx, router)go rw.run(bs.closeCh, bs.wg)sw : newStoreWorker(ctx, bs.store…

基于Web API drap事件的简单拖拽功能

基于Web API drap事件的简单拖拽功能 效果示例图代码示例 效果示例图 代码示例 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style type"text/css">* {padding: 0px;margin: 0px;box-s…

uniapp动态获取列表中每个下标的高度赋值给另一个数组(完整代码附效果图)

uniapp实现动态获取列表中每个下标的高度&#xff0c;赋值给另一个数组。 先看效果图&#xff1a; 完整代码&#xff1a; <template><div class""><div class"">我是A列表&#xff0c;我的高度不是固定的</div><div class&qu…

MySQL 坐标批量计算及优化

文章目录 1、坐标计算2、优化 现在有一个需求&#xff0c;就是找出距离某用户最近的一些点&#xff0c;一种实现方法就是调用地图的api来计算筛选&#xff0c;另外一种就是在数据库中计算&#xff0c;考虑到地图api有并发量限制&#xff0c;所以选用数据库计算的方式。 1、坐标…

ThunderScope开源示波器

简介 4CH&#xff0c;1GSa/S 开源示波器。前端很简洁&#xff0c;BUF802LMH6518&#xff0c;ADC是HMCAD1511&#xff0c;用Xilinx A7 FPGA进行控制&#xff0c;数据通过PCIE总线传输到上位机处理。目前这个项目已经被挂到了Xilinx官网&#xff0c;强。 设计日志&#xff1a;h…

Unity自定义后处理——Vignette暗角

大家好&#xff0c;我是阿赵。   继续说一下屏幕后处理的做法&#xff0c;这一期讲的是Vignette暗角效果。 一、Vignette效果介绍 Vignette暗角的效果可以给画面提供一个氛围&#xff0c;或者模拟一些特殊的效果。 还是拿这个角色作为底图 添加了Vignette效果后&#xff0…

软件测试银行项目面试过程

今天参加了一场比较正式的面试&#xff0c;汇丰银行的视频面试。在这里把面试的流程记录一下&#xff0c;结果还不确定&#xff0c;但是面试也是自我学习和成长的过程&#xff0c;所以记录下来大家也可以互相探讨一下。 请你做一下自我介绍&#xff1f;&#xff08;汇丰要求英…

第108天:免杀对抗-Python混淆算法反序列化打包生成器Py2exeNuitka

知识点 #知识点&#xff1a; 1、Python-对执行代码做文章 2、Python-对shellcode做文章 3、Python-对代码打包器做文章#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳花指…

webpack打包之 copy-webpack-plugin

copy-webpack-plugin 打包复制文件插件。 1、什么时候要使用&#xff1f; 在离线应用中&#xff0c;前端所有文件都需在在本地&#xff0c;有些文件&#xff08;比如iconFont以及一些静态img)需要转为离线文件&#xff0c;这些文件可以直接引用更方便些&#xff0c;这就需要在打…

6.6Jmeter远程调度Linux机器Jmeter测试

1、配置Agent和启动 1.1、打开jmeter/bin目录下的jmeter.properties 1、server_port1099取消注释 2、remote_hosts127.0.0.1 改为remote_hosts127.0.0.1:1099 或者是remote_hostsAgent机的ip:1099 3、server.rmi.localport1099 4、server.rmi.ssl.disablefalse改为true&#x…

基于springboot+Redis的前后端分离项目之分布式锁(四)-【黑马点评】

&#x1f381;&#x1f381;资源文件分享 链接&#xff1a;https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA?pwdeh11 提取码&#xff1a;eh11 分布式锁 分布式锁1 、基本原理和实现方式对比2 、Redis分布式锁的实现核心思路3 、实现分布式锁版本一4 、Redis分布式锁误删情况…

基于SpringBoot+Vue+微信小程序的电影平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 研究背景&#xff1a;…

Hyperledger Fabric测试网络的准备和基本使用

文章目录 相关安装启动测试网络创建channel打包链码安装链码包通过链码定义链码定义提交给通道调用链码关闭网络遇到的问题1.docker保持启动状态2.忘起测试网络了3.Java版本过高&#xff0c;推荐1.8 相关安装 npm、node、git、docker、docker-compose。docker保证一直运行 serv…

基于springboot的微信小程序宠物领养医院系统(源代码+数据库+10000字论文)085

基于springboot的微信小程序宠物领养医院系统(源代码数据库10000字论文)085 一、系统介绍 本项目有网页版和小程序端 本系统分为管理员、医生、用户三种角色 用户角色包含以下功能&#xff1a; 登录、注册、宠物领养、医生在线咨询、查看挂号、个人中心、密码修改、宠物寄…