微信小程序用户登录及头像昵称设置教程(前后端)

目录

1.背景分析

2.具体需求分析

3.前端设计

3.1 用户登录

3.2 头像昵称填写(个人信息界面)

4.后端设计

4.1项目架构分析

4.2 代码分析

实体类

dao层

service层

controller层

工具类

5.nginx部署

6.效果演示

1.背景分析

众所周知,微信小程序获取用户信息的接口经过了好几次调整,目前来说【wx.getUserProfile】 和【wx.getUserInfo】 这两个获取用户信息的接口都已经停用了,取而代之的是【头像昵称填写能力】:

详见小程序用户头像昵称获取规则调整公告:小程序用户头像昵称获取规则调整公告 | 微信开放社区

而与此同时,手机号快速验证组件将需要付费使用,及【获取用户手机号码】的功能要收费了....

详见:手机号快速验证组件 | 微信开放文档

这样的调整无疑会对用户身份信息的获取以及用户登录产生一定的影响,因此在本demo中采用【wx.login】进行登录,而不是获取用户手机号码进行登录;

在用户头像和昵称获取方面采用最新的接口来实现;

2.具体需求分析

前端页面:

  1. 登录页面:登录按钮
  2. 个人信息页面:展示/设置用户头像及昵称

流程:

  • 在登录页面,用户点击按钮进行登录,需要判断用户是否已经登录过
    • 如果用户尚未登录,为用户自动进行注册
    • 如果用户已经登录过,则需要获取到用户之前已经设置过的用户头像和昵称,并展示在个人信息页面
  • 在个人信息页面:
    • 需要保证用户此时已经登录
    • 用户可以设置头像,将设置的头像发送到服务器进行保存
    • 用户可以设置昵称,将设置的昵称发送到服务器进行保存

数据库设计: 共有一张数据表:【user表】

user_id:用户id,用户身份的唯一标识,以微信用户的openid作为用户id

user_avatarurl:用户头像

user_name:用户昵称

技术栈:

  • 前端:微信小程序原生开发,基于微信官方案例拓展
  • 后端:采用SpringBoot框架开发,接口运行在本地
  • 服务器:采用华为云服务器,部署nginx,主要功能是保存图片资源并提供静态资源访问的接口

3.前端设计

3.1 用户登录

用户登录全流程详见:小程序登录 | 微信开放文档

包括前后端对接以及微信接口服务的调用;

在前端开发部分主要使用的是微信提供的【wx.login】API: 接口文档:wx.login(Object object) | 微信开放文档

login页面具体设计如下:

①login.wxml:

一个简单的按钮组件,绑定【login】方法:

<view class="container">
<button type="primary" bindtap="login">点此登录</button>
</view>

②login.wxss:

.container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}

对按钮的位置进行居中设置,需要注意的是这里的【height】不能设置100%,否则垂直居中不起作用

vh,是css相对视口高度。1vh=1%*视口高度

至此页面绘制完毕,很简单:

③login.js:

Page({data: {},login() {wx.login({success: (res) => {console.log(res)var code = res.code //获取codewx.request({ //调用后端接口url: 'http://localhost:8080/login', method: 'POST',header: {'content-type': 'application/json'},data: {code: code, //请求体中封装code},success(res){console.log(res)//页面跳转wx.navigateTo({//携带用户头像信息和用户昵称信息url: '/index/index?userAvatarUrl=' + res.data.data.userAvatarUrl + '&userName=' + res.data.data.userName,})}})},})}
})

主要逻辑就是前端通过【wx.login】获取code,然后后端拿到code之后通过调用 微信服务端的【auth.code2Session】接口来换取用户唯一身份标识openId

如果用户不是第一次登录,则可能在之前的登录中设置过头像和昵称,因此后端接口的返回信息中需要有通过openId查询到的用户头像和用户昵称,前端获取到这些信息后通过页面跳转携带这些信息到达个人信息界面;

3.2 头像昵称填写(个人信息界面)

参考微信官方文档的【头像昵称填写功能】:

头像昵称填写 | 微信开放文档

需要注意该功能从基础库 2.21.2 开始支持,因此需要检查开发者工具中【调试基础库的版本】

具体的前端代码参考了官方案例:

点击【在开发者工具中预览效果】即可下载代码

①index.wxml:

展示用户头像和昵称:

<!--个人信息页面--><view data-weui-theme="{{theme}}">
<!--用户头像-->
<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
<image class="avatar" src="{{avatarUrl}}"></image>
</button><!--用户昵称-->
<mp-form>
<mp-cells>
<mp-cell title="昵称">
<input type="nickname" class="weui-input" placeholder="请输入昵称"
bind:change="getNickName" value="{{nickName}}"/>
</mp-cell>
</mp-cells>
</mp-form>
</view>

②index.wxss:页面简单布局

.avatar-wrapper {padding: 0;width: 56px !important;border-radius: 8px;margin-top: 40px;margin-bottom: 40px;
}.avatar {display: block;width: 56px;height: 56px;
}.container {display: flex;
}

③index.json:

导入了【weui】这个组件库,是官方案例中采用的组件库

相关信息可以参考:WeUI组件库简介 | 微信开放文档

这个组件库本人没用过,但可以推荐一款比较好用的组件库:Vant Weapp - 轻量、可靠的小程序 UI 组件库

{"usingComponents": {"mp-form-page": "weui-miniprogram/form-page/form-page","mp-form": "weui-miniprogram/form/form","mp-cells": "weui-miniprogram/cells/cells","mp-cell": "weui-miniprogram/cell/cell"},"pageOrientation": "auto","navigationBarTitleText": "我的"
}

注意,如果不是直接下载的官方案例,而是自己想要用的话,不要忘记在【app.json】中设置:

至此页面绘制完毕:

接下来是js的逻辑:

④index.js:

const app = getApp()//默认头像
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'Page({data: {avatarUrl: defaultAvatarUrl, //用户头像theme: wx.getSystemInfoSync().theme,nickName: "" //用户昵称},//onLoad方法onLoad(options) {//接收到登录页面传过来的头像和昵称if (options.userAvatarUrl != "null") { //进行判空处理this.setData({//这里的地址是华为云服务器的地址,需要进行nginx配置avatarUrl: "http://117.78.3.175/" + options.userAvatarUrl})}if (options.userName != "null") {this.setData({nickName: options.userName})}//监听主题改变事件(与本demo功能无关)wx.onThemeChange((result) => {this.setData({theme: result.theme})})},//用户选择头像onChooseAvatar(e) {var that = this;console.log(e.detail)const {avatarUrl} = e.detailthis.setData({avatarUrl})//对临时图片链接进行base64编码var avatarUrl_base64 = 'data:image/jpeg;base64,' + wx.getFileSystemManager().readFileSync(this.data.avatarUrl, 'base64')//将编码后的图片发送到服务器进行存储wx.request({url: 'http://localhost:8080/upLoadImage',method: 'POST',header: {'content-type': 'application/json'},data: {avatarUrl: avatarUrl_base64, //请求体中封装编码后的图片},success(res) {console.log(res)}})},//获取用户昵称getNickName(e) {var that = this;var username = e.detail.value//将编码后的图片发送到服务器进行存储wx.request({url: 'http://localhost:8080/setUserName',method: 'POST',header: {'content-type': 'application/json'},data: {username: username, //请求体中封装编码后的图片},success(res) {console.log(res)that.setData({nickName: e.detail.value})}})}
})

一共需要访问两个接口:设置用户头像和设置用户昵称

简单的流程就是用户在前端设置好头像/昵称之后将设置的内容发送到后端接口,然后进行持久化的存储;

这里需要特别注意的是用户头像的处理,因为通过微信最新提供的【头像昵称获取能力】,我们获取到的头像是一个临时链接,其格式如下:

http://tmp/FQvGKAKmSs4fef9778ae6f68da86726aa6992beae979.jpeg

这个链接在浏览器中也是无法打开的

因此我们无法直接将这个链接存储到数据库中,否则下一次访问的时候这个链接就失效了,起不到持久化存储的作用;

解决方法:

  • 对临时图片链接进行base64编码,发送到后端接口,在后端对编码后的数据进行解码,得到字节数组,然后将字节数组通过jsch框架提供的sftp文件上传通道上传到华为云服务器,并将该图片的名称存储到数据库中
  • 在华为云服务器上安装nginx来访问静态资源,这样我们获取到云服务器的ip地址以及图片资源的名称(数据库中存储了)后即可访问图片资源

 

4.后端设计

采用SpringBoot + Maven + Mybatis 进行开发,maven版本是3.6.3

有关环境配置相关内容参考:百度翻译API使用教程(前端+后端)_百度翻译接口_THE WHY的博客-CSDN博客

的后端代码部分,这里不再赘述

由于我创建SpringBoot项目使用的是专业版的IDEA,所以如果不是专业版的IDEA,可以自己配置SpringBoot环境,项目中使用到的pom.xml依赖提供如下:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!--hutool工具类--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.16</version></dependency><!--mybatis和MySQL依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.2</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>3.0.2</version><scope>test</scope></dependency><!--sftp文件上传--><dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.54</version></dependency>

4.1项目架构分析

4.2 代码分析

实体类

①User:用户类

public class User {private String userId; //idpublic String userAvatarUrl; //头像public String userName; //昵称public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}public String getUserAvatarUrl() {return userAvatarUrl;}public void setUserAvatarUrl(String userAvatarUrl) {this.userAvatarUrl = userAvatarUrl;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}@Overridepublic String toString() {return "User{" +"userId='" + userId + '\'' +", userAvatarUrl='" + userAvatarUrl + '\'' +", userName='" + userName + '\'' +'}';}
}

②Code:状态码:定义了返回前端的状态码

package com.why.entity;public class Code {public static final Integer LOGIN_ALREADY = 10001; //用户已经登录public static final Integer LOGIN_NOT = 10002; //用户尚未登录public static final Integer IMAGE_SET_SUCCESS = 10011; //图片上传成功public static final Integer IMAGE_SET_FAIL = 10012; //图片上传失败public static final Integer NAME_SET_SUCCESS = 10021; //名字设置成功public static final Integer NAME_SET_FAIL = 10022; //名字设置失败public static final Integer ERROR = 20000; //服务器错误}

③Result:定义了返回前端的数据的格式:

package com.why.entity;public class Result {private Object data;private Integer code;private String msg;public Result(Object data, Integer code, String msg) {this.data = data;this.code = code;this.msg = msg;}public Result(Integer code, String msg) {this.code = code;this.msg = msg;}public Result(Object data, Integer code) {this.data = data;this.code = code;}@Overridepublic String toString() {return "Result{" +"data=" + data +", code=" + code +", msg='" + msg + '\'' +'}';}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}

④WXContent:微信小程序相关内容,包括获取openid需要使用的appid和appsecret:

public class WXContent {public static final String APPID = "你的APPID";public static final String APPSECRET = "你的APPSECRET";}

 

dao层

UserDao:

@Mapper
public interface UserDao {/*** 获取用户所有信息* @return*/@Select("select * from user")public List<User> getAll();/*** 用户注册* @param userId* @return*/@Insert("insert into user(user_id) values(#{userId})")public int insertId(String userId);/*** 用户设置头像* @param userId* @param image* @return*/@Insert("update user set user_avatarurl = #{image} where user_id = #{userId}")public int insertImage(String userId, String image);/*** 用户设置昵称* @param userId* @param name* @return*/@Insert("update user set user_name = #{name} where user_id = #{userId}")public int insertName(String userId, String name);/*** 查看所有用户* @param openid* @return*/@Select("select user_id as userId, user_avatarurl as userAvatarUrl, user_name as userName from user where user_id = #{openid}")public List<User> getById(String openid);}

采用mybatis的注解形式进行开发;

这里需要注意一下【查看所有用户】的方法:由于数据库中的字段名和User类中的变量名并不统一,因此我们可以通过赋别名的方法来让从数据库中查询出的内容装载到User类的实例中;

也可以采用xml文件的方式来进行配置,可以自行查找方法

 

service层

①UserService:

public interface UserService {public List<User> getAll();public int insertId(String userId);public int insertImage(String userId, String image);public int insertName(String userId, String name);public List<User> getById(String openid);}

②UserServiceImpl:

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Overridepublic List<User> getAll() {return userDao.getAll();}@Overridepublic int insertId(String userId) {return userDao.insertId(userId);}@Overridepublic int insertImage(String userId, String image) {return userDao.insertImage(userId, image);}@Overridepublic int insertName(String userId, String name) {return userDao.insertName(userId, name);}@Overridepublic List<User> getById(String openid) {return userDao.getById(openid);}
}

controller层

UserController:(一共有三个接口:登录/上传图片/设置昵称)

@RestController
public class UserController {@Autowiredprivate UserService userService;private String openid = "";/*** 用户登录* @param data* @return*/@PostMapping("/login")public Result login(@RequestBody Map<String,Object> data){String code = data.get("code").toString();String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + WXContent.APPID + "&secret=" + WXContent.APPSECRET+ "&js_code=" + code + "&grant_type=authorization_code";RestTemplate restTemplate = new RestTemplate();MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_HTML,MediaType.TEXT_PLAIN));restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);ResponseEntity<Map> response = restTemplate.getForEntity(url,Map.class);openid = (String) response.getBody().get("openid");List<User> users = userService.getById(openid);if (users.size() == 0){//用户尚未注册userService.insertId(openid);return new Result(openid,Code.LOGIN_NOT,"登录成功!已为您注册账号");}else {//用户已经注册过Map<String, String> resultData = new HashMap<>();String userAvatarUrl = users.get(0).getUserAvatarUrl();resultData.put("userAvatarUrl",userAvatarUrl);String userName = users.get(0).getUserName();resultData.put("userName",userName);return new Result(resultData,Code.LOGIN_ALREADY,"登录成功!欢迎回来");}}/*** 向服务器上传图片* @param data* @return* @throws Exception*/@PostMapping("/upLoadImage")public Result upLoadImage(@RequestBody Map<String,Object> data) throws Exception {//获取base64编码的数据String avatarUrl = data.get("avatarUrl").toString();String avatarUrlBase64 = avatarUrl.split(",")[1];//将其解码成字节数组Base64.Decoder decoder = Base64.getDecoder();byte[] bytes = decoder.decode(avatarUrlBase64);//通过jsch上传至服务器if ("".equals(openid)){return new Result(Code.LOGIN_NOT,"用户尚未登录,无法设置头像");}else {MD5 md5 = MD5.create();String imageName = md5.digestHex16(openid) + ".png";System.out.println(imageName);try {int flag = userService.insertImage(openid,imageName);if (flag != 0){SSHUtils.sftp(bytes,imageName);return new Result(Code.IMAGE_SET_SUCCESS,"图片上传成功");}else {return new Result(Code.IMAGE_SET_FAIL,"图片上传失败");}}catch (Exception e){return new Result(Code.ERROR,"服务器错误");}}}/*** 设置昵称* @param data* @return*/@PostMapping("/setUserName")public Result setUserName(@RequestBody Map<String,Object> data){String username = data.get("username").toString();try {int flag = userService.insertName(openid, username);if (flag != 0){return new Result(Code.NAME_SET_SUCCESS,"设置昵称成功");}else {return new Result(Code.NAME_SET_FAIL,"昵称设置失败");}} catch (Exception e){return new Result(Code.ERROR,"服务器错误");}}}
  • 其中【login】接口的开发可以参考:小程序登录 | 微信开放文档;由于【RestTemplate】默认不支持text_plain格式,所以我们需要通过【MappingJackson2HttpMessageConverter】来添加text_plain格式,否则会报错;
  • 【upLoadImage】的开发需要参考下面的工具类SSHUtils,就是解码base64格式的文件,然后通过sftp通道上传到服务器

工具类

SSHUtils:实现文件上传的功能

public class SSHUtils {/*** \文件上传* @param fileBytes 文件字节数组* @param fileName 文件名* @throws Exception*/public static void sftp(byte[] fileBytes,String fileName) throws Exception{String ip = "你的服务器ip地址"; //ip地址String username = "用户名"; //用户名String password = "密码"; //密码int port = 22; //端口号String filePath = "文件路径"; //文件路径JSch jsch = new JSch();//创建session连接Session session = jsch.getSession(username, ip ,port);if (session == null) {throw new Exception("session create error");}session.setPassword(password);//设置密码session.setConfig("StrictHostKeyChecking", "no"); //设置登陆提示为"no"session.connect(1000); //设置超时时间//创建通信通道Channel channel = (Channel) session.openChannel("sftp");if (channel == null){throw new Exception("channel create error");}channel.connect(1000); //设置超时时间ChannelSftp sftp = (ChannelSftp) channel; //创建sftp通道OutputStream outputStream = null;//开始文件上传try {sftp.cd(filePath); //进入指定文件路径outputStream =sftp.put(fileName);outputStream.write(fileBytes);}catch (Exception e) {e.printStackTrace();throw new Exception("file upload failed");} finally {if(outputStream != null){ //关闭文件流outputStream.flush();outputStream.close();}if(channel != null){ //关闭通道channel.disconnect();}if(session != null){ //关闭链接session.disconnect();}}}
}

 

5.nginx部署

1.安装所需的安装包的编译环境:

yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make

 

2.到官网下载并解压:

官网网址:nginx: download

下载完成后解压:tar zxvf nginx-1.20.2.tar.gz -C /opt/

 

3.安装:

首先进入nginx的解压目录,然后执行指令:

./configure && make && make install

(默认的安装路径是/usr/local/nginx)

 

4.启动nginx:

/usr/local/nginx/sbin/nginx

通过netstat -anp | grep 80可以检查nginx是否正常启动;

如下所示则正常启动:

使用指令:/usr/local/nginx/sbin/nginx -s stop 可以关闭nginx服务器;

 

5.配置静态资源访问路径:

vim /usr/local/nginx/conf/nginx.conf

添加以下内容:

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css)$ {
root /usr/local/nginx/html/images;
expires 10d;
}

如下:

含义及对于图片等静态资源的访问都会转到/usr/local/nginx/html/images路径下,因此我们的用户头像资源也需要上传到该路径下

 

6.效果演示

用户处于登录状态下,可以自动获取之前设置的头像和昵称,并进行填写,如下所示:

mmexportde07eb109ca31107f60337acc72522d3_1689585185432.gif

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

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

相关文章

论文解读|VoxelNet:基于点云的3D物体检测的端到端学习

原创 | 文 BFT机器人 01 摘要 论文提出了表述了一个新的基于点云的3D检测方法&#xff0c;名为VoxelNet&#xff0c;该方法是一个端到端可训练的深度学习架构&#xff0c;利用了稀疏点云的结构特性&#xff0c;直接在稀疏的3D点上进行操作&#xff0c;并通过高效的并行处理体素…

01 - 如何制定性能调优标准?

1、为什么要做性能调优&#xff1f; 一款线上产品如果没有经过性能测试&#xff0c;那它就好比是一颗定时炸弹&#xff0c;你不知道它什么时候会出现问题&#xff0c;你也不清楚它能承受的极限在哪儿。 有些性能问题是时间累积慢慢产生的&#xff0c;到了一定时间自然就爆炸了…

Linux —— 进程状态

目录 一&#xff0c;进程状态分类 二&#xff0c;僵尸进程 三&#xff0c;孤儿进程 一&#xff0c;进程状态分类 进程状态反应进程执行过程中的变化&#xff0c;状态会随外界条件的变化而转换&#xff1b; 三态模型&#xff0c;运行态、就绪态、阻塞态&#xff1b;五态模型…

SpringCloud微服务(三)RabbitMQ、SpringAMQP、elasticsearch、DSL、MQ、ES详细介绍

目录 一、初始MQ 同步调用 异步调用 什么是MQ 执行下面的命令来运行MQ容器&#xff1a; 如果冲突了&#xff0c;可以先查询 RabbitMQ概述 常见消息模型 HelloWorld案例 二、SpringAMQP 引入依赖 Work Queue 消费预取限制 ​编辑 发布、订阅 发布订阅Fanout Ex…

进阶C语言——字符串和内存函数

今天我们学点库函数 字符函数和字符串函数 求字符串长度函数->strlen strlen需要的头文件是string.h ,那它的作用是什么呢&#xff1f;&#xff1f; 他是来求字符串长度的&#xff0c;统计的是’\0’前的字符串长度 #include<stdio.h> #include<string.h> int …

紫光展锐CEO任奇伟博士:用芯赋能,共建XR新生态

7月6日&#xff0c;2023世界人工智能大会在上海世博中心及世博展览馆盛大开幕。紫光集团高级副总裁、紫光展锐CEO任奇伟博士受邀出席芯片主题论坛&#xff0c;并发表题为《用芯赋能&#xff0c;共建XR新生态》的演讲。 世界人工智能大会自2018年创办以来已成功举办五届&#xf…

1.4 MVP矩阵

MVP矩阵代表什么 MVP矩阵分别是模型&#xff08;Model&#xff09;、观察&#xff08;View&#xff09;、投影&#xff08;Projection&#xff09;三个矩阵。 我们的顶点坐标起始于局部空间&#xff08;Local Space&#xff09;&#xff0c;在这里他成为局部坐标&#xff08;L…

面试题更新之-DOCTYPE html相关问题

文章目录 <!DOCTYPE html>是什么&#xff1f;为什么要在html文件开头加上一个<!DOCTYPE html>DOCTYPE的作用&#xff0c;严格与混杂模式的区别&#xff0c;有何意义HTML5为什么只需要写<!DOCTYPE HTML> 是什么&#xff1f; 是HTML文档的文档类型声明&#xf…

Redis进阶

Redis之父安特雷兹 redis x.x.x第二位是偶数的是稳定版本 redis7安装单机物理机安装&#xff1a; https://blog.csdn.net/G189D/article/details/129185947 数据类型 bitmap 统计二值状态的数据类型 最大位数2^32位&#xff0c;他可以极大的节约存储空间&#xff0c;使用…

postman 自动化测试

postman 自动化测试 0、写在前面1、变量引用1.1、如何在请求体中引用变量 0、写在前面 在有些时候看官方文档 比网上搜索效率要高&#xff0c; 比如网上搜一通还是不知道用法或者没有搜索到你想要的用法的时候。 postman官方文档 : https://learning.postman.com/docs/introdu…

layui选项卡演示

layui选项卡演示 .1 引入layui2. 选项卡演示实列3.js分离的代码4运行结果 在前端开发中&#xff0c;选项卡常用于展示多个内容模块&#xff0c;提供用户友好的界面交互方式。layui作为一款简洁易用的前端框架&#xff0c;提供了丰富的组件库&#xff0c;其中包括了强大且易用的…

《MySQL》事务

文章目录 概念事务的操作属性&#xff08;aicd&#xff09; 概念 一组DML语句&#xff0c;这组语句要一次性执行完毕&#xff0c;是一个整体 为什么要有事务&#xff1f; 为应用层提供便捷服务 事务的操作 有一stu表 # 查看事务提交方式(默认是开启的) show variables like au…

pytorch深度学习逻辑回归 logistic regression

# logistic regression 二分类 # 导入pytorch 和 torchvision import numpy as np import torch import torchvision from torch.autograd import Variable import torch.nn as nn import torch.nn.functional as F import torch.optim as optim import matplotlib.pyplot as …

Kafka第二课-代码实战、参数配置详解、设计原理详解

一、代码实战 一、普通java程序实战 引入依赖 <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>2.4.1</version></dependency><dependency>&l…

Ceph的安装部署

文章目录 一、存储基础1.1 单机存储设备1.2 单机存储的问题1.3分布式存储&#xff08;软件定义的存储 SDS&#xff09; 二、Ceph 简介2.1 Ceph 优势2.2 Ceph 架构2.3 Ceph 核心组件2.4 Pool、PG 和 OSD 的关系&#xff1a;2.5 OSD 存储后端2.6 Ceph 数据的存储过程2.7 Ceph 版本…

面向初学者的卷积神经网络

卷积神经网络在机器学习中非常重要。如果你想做计算机视觉或图像识别任务&#xff0c;你根本离不开它们。但是很难理解它们是如何工作的。 在这篇文章中&#xff0c;我们将讨论卷积神经网络背后的机制、它的优点和应用领域。 什么是神经网络&#xff1f; 首先&#xff0c;让…

架构训练营:3-3设计备选方案与架构细化

3架构中期 什么是备选架构&#xff1f; 备选架构定义了系统可行的架构模式和技术选型 备选方案筛选过程 头脑风暴 &#xff1a;对可选技术进行排列组合&#xff0c;得到可能的方案 红线筛选&#xff1a;根据系统明确的约束和限定&#xff0c;一票否决某些方案&#xff08;主要…

Docker 安装 Nginx,并实现负载均衡

1、获取 nginx 的镜像 # 默认是latest版本docker pull nginx 2、运行 nginx 容器 docker run --name nginx-80 -p 80:80 --rm -d nginx# --name nginx-80 设定容器的名称# -p 80:80 端口进行映射&#xff0c;将本地的80端口映射到容器内部的80端口# --rm 表示容器退出后直接…

Vue中v-html用法以及指令汇总

操作数组的方法 &#xff1a; push&#xff1a;数组最后位置新增元素 pop&#xff1a; 删除最后一个元素 shift&#xff1a; 删除第一个元素 unshift&#xff1a;往前面加一个元素 splice&#xff1a;在数组的指定位置插入、删除、替换一个元素 sort&#xff1a; 数组排序…

卷积神经网络(CNN)原理详解

近些年人工智能发展迅速&#xff0c;在图像识别、语音识别、物体识别等各种场景上深度学习取得了巨大的成功&#xff0c;例如AlphaGo击败世界围棋冠军&#xff0c;iPhone X内置了人脸识别解锁功能等等&#xff0c;很多AI产品在世界上引起了很大的轰动。 而其中 卷积神经网络&am…