目錄
1.背景分析
2.具體需求分析
3.前端設(shè)計(jì)
3.1 用戶登錄
3.2 頭像昵稱填寫(個(gè)人信息界面)
4.后端設(shè)計(jì)
4.1項(xiàng)目架構(gòu)分析
4.2 代碼分析
實(shí)體類
dao層
service層
controller層
工具類
5.nginx部署
6.效果演示
1.背景分析
眾所周知,微信小程序獲取用戶信息的接口經(jīng)過了好幾次調(diào)整,目前來說【wx.getUserProfile】?和【wx.getUserInfo】?這兩個(gè)獲取用戶信息的接口都已經(jīng)停用了,取而代之的是【頭像昵稱填寫能力】:
詳見小程序用戶頭像昵稱獲取規(guī)則調(diào)整公告:小程序用戶頭像昵稱獲取規(guī)則調(diào)整公告 | 微信開放社區(qū)
而與此同時(shí),手機(jī)號(hào)快速驗(yàn)證組件將需要付費(fèi)使用,及【獲取用戶手機(jī)號(hào)碼】的功能要收費(fèi)了....
詳見:手機(jī)號(hào)快速驗(yàn)證組件 | 微信開放文檔
這樣的調(diào)整無疑會(huì)對(duì)用戶身份信息的獲取以及用戶登錄產(chǎn)生一定的影響,因此在本demo中采用【wx.login】進(jìn)行登錄,而不是獲取用戶手機(jī)號(hào)碼進(jìn)行登錄;
在用戶頭像和昵稱獲取方面采用最新的接口來實(shí)現(xiàn);
2.具體需求分析
前端頁面:
- 登錄頁面:登錄按鈕
- 個(gè)人信息頁面:展示/設(shè)置用戶頭像及昵稱
流程:
- 在登錄頁面,用戶點(diǎn)擊按鈕進(jìn)行登錄,需要判斷用戶是否已經(jīng)登錄過
- 如果用戶尚未登錄,為用戶自動(dòng)進(jìn)行注冊(cè)
- 如果用戶已經(jīng)登錄過,則需要獲取到用戶之前已經(jīng)設(shè)置過的用戶頭像和昵稱,并展示在個(gè)人信息頁面
- 在個(gè)人信息頁面:
- 需要保證用戶此時(shí)已經(jīng)登錄
- 用戶可以設(shè)置頭像,將設(shè)置的頭像發(fā)送到服務(wù)器進(jìn)行保存
- 用戶可以設(shè)置昵稱,將設(shè)置的昵稱發(fā)送到服務(wù)器進(jìn)行保存
數(shù)據(jù)庫設(shè)計(jì): 共有一張數(shù)據(jù)表:【user表】
user_id:用戶id,用戶身份的唯一標(biāo)識(shí),以微信用戶的openid作為用戶id
user_avatarurl:用戶頭像
user_name:用戶昵稱
技術(shù)棧:
- 前端:微信小程序原生開發(fā),基于微信官方案例拓展
- 后端:采用SpringBoot框架開發(fā),接口運(yùn)行在本地
- 服務(wù)器:采用華為云服務(wù)器,部署nginx,主要功能是保存圖片資源并提供靜態(tài)資源訪問的接口
3.前端設(shè)計(jì)
3.1 用戶登錄
用戶登錄全流程詳見:小程序登錄 | 微信開放文檔
包括前后端對(duì)接以及微信接口服務(wù)的調(diào)用;
在前端開發(fā)部分主要使用的是微信提供的【wx.login】API: 接口文檔:wx.login(Object object) | 微信開放文檔
login頁面具體設(shè)計(jì)如下:
①login.wxml:
一個(gè)簡單的按鈕組件,綁定【login】方法:
<view class="container">
<button type="primary" bindtap="login">點(diǎn)此登錄</button>
</view>
②login.wxss:
.container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
對(duì)按鈕的位置進(jìn)行居中設(shè)置,需要注意的是這里的【height】不能設(shè)置100%,否則垂直居中不起作用
vh,是css相對(duì)視口高度。1vh=1%*視口高度
至此頁面繪制完畢,很簡單:
③login.js:
Page({
data: {
},
login() {
wx.login({
success: (res) => {
console.log(res)
var code = res.code //獲取code
wx.request({ //調(diào)用后端接口
url: 'http://localhost:8080/login',
method: 'POST',
header: {
'content-type': 'application/json'
},
data: {
code: code, //請(qǐng)求體中封裝code
},
success(res)
{
console.log(res)
//頁面跳轉(zhuǎn)
wx.navigateTo({
//攜帶用戶頭像信息和用戶昵稱信息
url: '/index/index?userAvatarUrl=' + res.data.data.userAvatarUrl + '&userName=' + res.data.data.userName,
})
}
})
},
})
}
})
主要邏輯就是前端通過【wx.login】獲取code,然后后端拿到code之后通過調(diào)用 微信服務(wù)端的【auth.code2Session】接口來換取用戶唯一身份標(biāo)識(shí)openId
如果用戶不是第一次登錄,則可能在之前的登錄中設(shè)置過頭像和昵稱,因此后端接口的返回信息中需要有通過openId查詢到的用戶頭像和用戶昵稱,前端獲取到這些信息后通過頁面跳轉(zhuǎn)攜帶這些信息到達(dá)個(gè)人信息界面;
3.2 頭像昵稱填寫(個(gè)人信息界面)
參考微信官方文檔的【頭像昵稱填寫功能】:
頭像昵稱填寫 | 微信開放文檔
需要注意該功能從基礎(chǔ)庫 2.21.2 開始支持,因此需要檢查開發(fā)者工具中【調(diào)試基礎(chǔ)庫的版本】
具體的前端代碼參考了官方案例:
點(diǎn)擊【在開發(fā)者工具中預(yù)覽效果】即可下載代碼
①index.wxml:
展示用戶頭像和昵稱:
<!--個(gè)人信息頁面-->
<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="請(qǐng)輸入昵稱"
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:
導(dǎo)入了【weui】這個(gè)組件庫,是官方案例中采用的組件庫
相關(guān)信息可以參考:WeUI組件庫簡介 | 微信開放文檔
這個(gè)組件庫本人沒用過,但可以推薦一款比較好用的組件庫: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】中設(shè)置:
至此頁面繪制完畢:
接下來是js的邏輯:
④index.js:
const app = getApp()
//默認(rèn)頭像
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
Page({
data: {
avatarUrl: defaultAvatarUrl, //用戶頭像
theme: wx.getSystemInfoSync().theme,
nickName: "" //用戶昵稱
},
//onLoad方法
onLoad(options) {
//接收到登錄頁面?zhèn)鬟^來的頭像和昵稱
if (options.userAvatarUrl != "null") { //進(jìn)行判空處理
this.setData({
//這里的地址是華為云服務(wù)器的地址,需要進(jìn)行nginx配置
avatarUrl: "http://117.78.3.175/" + options.userAvatarUrl
})
}
if (options.userName != "null") {
this.setData({
nickName: options.userName
})
}
//監(jiān)聽主題改變事件(與本demo功能無關(guān))
wx.onThemeChange((result) => {
this.setData({
theme: result.theme
})
})
},
//用戶選擇頭像
onChooseAvatar(e) {
var that = this;
console.log(e.detail)
const {
avatarUrl
} = e.detail
this.setData({
avatarUrl
})
//對(duì)臨時(shí)圖片鏈接進(jìn)行base64編碼
var avatarUrl_base64 = 'data:image/jpeg;base64,' + wx.getFileSystemManager().readFileSync(this.data.avatarUrl, 'base64')
//將編碼后的圖片發(fā)送到服務(wù)器進(jìn)行存儲(chǔ)
wx.request({
url: 'http://localhost:8080/upLoadImage',
method: 'POST',
header: {
'content-type': 'application/json'
},
data: {
avatarUrl: avatarUrl_base64, //請(qǐng)求體中封裝編碼后的圖片
},
success(res) {
console.log(res)
}
})
},
//獲取用戶昵稱
getNickName(e) {
var that = this;
var username = e.detail.value
//將編碼后的圖片發(fā)送到服務(wù)器進(jìn)行存儲(chǔ)
wx.request({
url: 'http://localhost:8080/setUserName',
method: 'POST',
header: {
'content-type': 'application/json'
},
data: {
username: username, //請(qǐng)求體中封裝編碼后的圖片
},
success(res) {
console.log(res)
that.setData({
nickName: e.detail.value
})
}
})
}
})
一共需要訪問兩個(gè)接口:設(shè)置用戶頭像和設(shè)置用戶昵稱
簡單的流程就是用戶在前端設(shè)置好頭像/昵稱之后將設(shè)置的內(nèi)容發(fā)送到后端接口,然后進(jìn)行持久化的存儲(chǔ);
這里需要特別注意的是用戶頭像的處理,因?yàn)橥ㄟ^微信最新提供的【頭像昵稱獲取能力】,我們獲取到的頭像是一個(gè)臨時(shí)鏈接,其格式如下:
http://tmp/FQvGKAKmSs4fef9778ae6f68da86726aa6992beae979.jpeg
這個(gè)鏈接在瀏覽器中也是無法打開的
因此我們無法直接將這個(gè)鏈接存儲(chǔ)到數(shù)據(jù)庫中,否則下一次訪問的時(shí)候這個(gè)鏈接就失效了,起不到持久化存儲(chǔ)的作用;
解決方法:
- 對(duì)臨時(shí)圖片鏈接進(jìn)行base64編碼,發(fā)送到后端接口,在后端對(duì)編碼后的數(shù)據(jù)進(jìn)行解碼,得到字節(jié)數(shù)組,然后將字節(jié)數(shù)組通過jsch框架提供的sftp文件上傳通道上傳到華為云服務(wù)器,并將該圖片的名稱存儲(chǔ)到數(shù)據(jù)庫中
- 在華為云服務(wù)器上安裝nginx來訪問靜態(tài)資源,這樣我們獲取到云服務(wù)器的ip地址以及圖片資源的名稱(數(shù)據(jù)庫中存儲(chǔ)了)后即可訪問圖片資源
4.后端設(shè)計(jì)
采用SpringBoot + Maven + Mybatis 進(jìn)行開發(fā),maven版本是3.6.3
有關(guān)環(huán)境配置相關(guān)內(nèi)容參考:百度翻譯API使用教程(前端+后端)_百度翻譯接口_THE WHY的博客-CSDN博客
的后端代碼部分,這里不再贅述
由于我創(chuàng)建SpringBoot項(xiàng)目使用的是專業(yè)版的IDEA,所以如果不是專業(yè)版的IDEA,可以自己配置SpringBoot環(huán)境,項(xiàng)目中使用到的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項(xiàng)目架構(gòu)分析
4.2 代碼分析
實(shí)體類
①User:用戶類
public class User {
private String userId; //id
public 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;
}
@Override
public String toString() {
return "User{" +
"userId='" + userId + '\'' +
", userAvatarUrl='" + userAvatarUrl + '\'' +
", userName='" + userName + '\'' +
'}';
}
}
②Code:狀態(tài)碼:定義了返回前端的狀態(tài)碼
package com.why.entity;
public class Code {
public static final Integer LOGIN_ALREADY = 10001; //用戶已經(jīng)登錄
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; //名字設(shè)置成功
public static final Integer NAME_SET_FAIL = 10022; //名字設(shè)置失敗
public static final Integer ERROR = 20000; //服務(wù)器錯(cuò)誤
}
③Result:定義了返回前端的數(shù)據(jù)的格式:
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;
}
@Override
public 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:微信小程序相關(guān)內(nèi)容,包括獲取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();
/**
* 用戶注冊(cè)
* @param userId
* @return
*/
@Insert("insert into user(user_id) values(#{userId})")
public int insertId(String userId);
/**
* 用戶設(shè)置頭像
* @param userId
* @param image
* @return
*/
@Insert("update user set user_avatarurl = #{image} where user_id = #{userId}")
public int insertImage(String userId, String image);
/**
* 用戶設(shè)置昵稱
* @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的注解形式進(jìn)行開發(fā);
這里需要注意一下【查看所有用戶】的方法:由于數(shù)據(jù)庫中的字段名和User類中的變量名并不統(tǒng)一,因此我們可以通過賦別名的方法來讓從數(shù)據(jù)庫中查詢出的內(nèi)容裝載到User類的實(shí)例中;
也可以采用xml文件的方式來進(jìn)行配置,可以自行查找方法
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 {
@Autowired
private UserDao userDao;
@Override
public List<User> getAll() {
return userDao.getAll();
}
@Override
public int insertId(String userId) {
return userDao.insertId(userId);
}
@Override
public int insertImage(String userId, String image) {
return userDao.insertImage(userId, image);
}
@Override
public int insertName(String userId, String name) {
return userDao.insertName(userId, name);
}
@Override
public List<User> getById(String openid) {
return userDao.getById(openid);
}
}
controller層
UserController:(一共有三個(gè)接口:登錄/上傳圖片/設(shè)置昵稱)
@RestController
public class UserController {
@Autowired
private 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)
{
//用戶尚未注冊(cè)
userService.insertId(openid);
return new Result(openid,Code.LOGIN_NOT,"登錄成功!已為您注冊(cè)賬號(hào)");
}
else {
//用戶已經(jīng)注冊(cè)過
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,"登錄成功!歡迎回來");
}
}
/**
* 向服務(wù)器上傳圖片
* @param data
* @return
* @throws Exception
*/
@PostMapping("/upLoadImage")
public Result upLoadImage(@RequestBody Map<String,Object> data) throws Exception {
//獲取base64編碼的數(shù)據(jù)
String avatarUrl = data.get("avatarUrl").toString();
String avatarUrlBase64 = avatarUrl.split(",")[1];
//將其解碼成字節(jié)數(shù)組
Base64.Decoder decoder = Base64.getDecoder();
byte[] bytes = decoder.decode(avatarUrlBase64);
//通過jsch上傳至服務(wù)器
if ("".equals(openid))
{
return new Result(Code.LOGIN_NOT,"用戶尚未登錄,無法設(shè)置頭像");
}
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,"服務(wù)器錯(cuò)誤");
}
}
}
/**
* 設(shè)置昵稱
* @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,"設(shè)置昵稱成功");
}
else {
return new Result(Code.NAME_SET_FAIL,"昵稱設(shè)置失敗");
}
} catch (Exception e)
{
return new Result(Code.ERROR,"服務(wù)器錯(cuò)誤");
}
}
}
- 其中【login】接口的開發(fā)可以參考:小程序登錄 | 微信開放文檔;由于【RestTemplate】默認(rèn)不支持text_plain格式,所以我們需要通過【MappingJackson2HttpMessageConverter】來添加text_plain格式,否則會(huì)報(bào)錯(cuò);
- 【upLoadImage】的開發(fā)需要參考下面的工具類SSHUtils,就是解碼base64格式的文件,然后通過sftp通道上傳到服務(wù)器
工具類
SSHUtils:實(shí)現(xiàn)文件上傳的功能
public class SSHUtils {
/**
* \文件上傳
* @param fileBytes 文件字節(jié)數(shù)組
* @param fileName 文件名
* @throws Exception
*/
public static void sftp(byte[] fileBytes,String fileName) throws Exception{
String ip = "你的服務(wù)器ip地址"; //ip地址
String username = "用戶名"; //用戶名
String password = "密碼"; //密碼
int port = 22; //端口號(hào)
String filePath = "文件路徑"; //文件路徑
JSch jsch = new JSch();
//創(chuàng)建session連接
Session session = jsch.getSession(username, ip ,port);
if (session == null) {
throw new Exception("session create error");
}
session.setPassword(password);//設(shè)置密碼
session.setConfig("StrictHostKeyChecking", "no"); //設(shè)置登陸提示為"no"
session.connect(1000); //設(shè)置超時(shí)時(shí)間
//創(chuàng)建通信通道
Channel channel = (Channel) session.openChannel("sftp");
if (channel == null)
{
throw new Exception("channel create error");
}
channel.connect(1000); //設(shè)置超時(shí)時(shí)間
ChannelSftp sftp = (ChannelSftp) channel; //創(chuàng)建sftp通道
OutputStream outputStream = null;
//開始文件上傳
try {
sftp.cd(filePath); //進(jìn)入指定文件路徑
outputStream =sftp.put(fileName);
outputStream.write(fileBytes);
}catch (Exception e) {
e.printStackTrace();
throw new Exception("file upload failed");
} finally {
if(outputStream != null){ //關(guān)閉文件流
outputStream.flush();
outputStream.close();
}
if(channel != null){ //關(guān)閉通道
channel.disconnect();
}
if(session != null){ //關(guān)閉鏈接
session.disconnect();
}
}
}
}
5.nginx部署
1.安裝所需的安裝包的編譯環(huán)境:
yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make
2.到官網(wǎng)下載并解壓:
官網(wǎng)網(wǎng)址:nginx: download
下載完成后解壓:tar zxvf nginx-1.20.2.tar.gz -C /opt/
3.安裝:
首先進(jìn)入nginx的解壓目錄,然后執(zhí)行指令:
./configure && make && make install
(默認(rèn)的安裝路徑是/usr/local/nginx)
4.啟動(dòng)nginx:
/usr/local/nginx/sbin/nginx
通過netstat -anp | grep 80可以檢查nginx是否正常啟動(dòng);
如下所示則正常啟動(dòng):
使用指令:/usr/local/nginx/sbin/nginx -s stop 可以關(guān)閉nginx服務(wù)器;
5.配置靜態(tài)資源訪問路徑:
vim /usr/local/nginx/conf/nginx.conf
添加以下內(nèi)容:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css)$ {
root /usr/local/nginx/html/images;
expires 10d;
}
如下:
含義及對(duì)于圖片等靜態(tài)資源的訪問都會(huì)轉(zhuǎn)到/usr/local/nginx/html/images路徑下,因此我們的用戶頭像資源也需要上傳到該路徑下
6.效果演示
用戶處于登錄狀態(tài)下,可以自動(dòng)獲取之前設(shè)置的頭像和昵稱,并進(jìn)行填寫,如下所示:文章來源:http://www.zghlxwxcb.cn/news/detail-577312.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-577312.html
到了這里,關(guān)于微信小程序用戶登錄及頭像昵稱設(shè)置教程(前后端)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!