1.问题描述
小程序登录接口升级之后,将之前的微信昵称和头像返回为微信用户和灰色头像,如下图所示:
2.解决方案
处理方案
引入微信小程序的最新临时对接方案:
选择或者上传微信头像
选择或者填写微信昵称
思路梳理
①微信授权获取空白头像和微信用户昵称
②新增获取最新用户数据代码,与数据库进行存储对接工作
③更新之后的用户则无需第二次的头像昵称信息的修改操作
效果展示
点击个人中心的灰色头像
显示操作页面
微信头像操作
微信昵称操作
完整操作截图
提交结果
修改成功最终跳转到自定义界面
完成后再次点击微信头像则不再进行修改的操作,也可以修改成可一直修改状态,根据具体需求进行开发即可!
3.代码部分
app.json
加入此页面的引入部分(app.json文件加入如下代码部分):
"pages/user_base/index",
小程序前端页面目录
/pages/user_base目录:
index.js
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
Page({
/**
* 页面的初始数据
*/
data: {
avatarUrl: defaultAvatarUrl,
theme: wx.getSystemInfoSync().theme,
},
onLoad: function (e) {
getApp().page.onLoad(this, e);
var t = this;
t.getDistrictData(function (e) {
area_picker.init({
page: t,
data: e
})
}), t.setData({
address_id: e.id
}), e.id && (getApp().core.showLoading({
title: "正在加载",
mask: !0
}), getApp().request({
url: getApp().api.user.address_detail,
data: {
id: e.id
},
success: function (e) {
getApp().core.hideLoading(), 0 == e.code && t.setData(e.data)
}
}))
},
onChooseAvatar(e) {
const { avatarUrl } = e.detail
this.setData({
avatarUrl:avatarUrl,
})
getApp().globalData.userInfo.avatarUrl = avatarUrl
console.log();
// getApp().core.setStorageSync(getApp().const.USER_INFO.avatar_url, avatarUrl);
},
//下列方法与上方方法一样,但是需要注意的是下方代码完善的是将图片存储服务器部分,而非只是记录手机端图片位置,切记需要使用下方完整版方法,上方方法仅作记录使用
onChooseAvatar(e) {
const { avatarUrl } = e.detail
this.setData({
avatarUrl:avatarUrl,
})
// const { avatarUrl } = e.detail
// this.setData({
// avatarUrl,
// })
let that = this
wx.uploadFile({
url: getApp().api.default.upload_image, //url地址如果不填写正确的话会不走下方方法,可以添加error方法进行抓取工作
// url:t.api.default.upload_image,
filePath: that.data.avatarUrl,
name: 'image',
success(res) {
// console.log(res);
if(res.statusCode == 200){
// wx.showToast({
// title: '网络异常,上传失败请重试!'
// })
var show_images = JSON.parse(res.data);
if(show_images.code == 0){
that.setData({
avatarUrl:show_images.data.url,
})
}else{
wx.showToast({
title: '网络异常,上传失败请重试!'
})
}
}else{
wx.showToast({
title: '网络异常,上传失败请重试!'
})
}
// console.log(JSON.parse(res.data));
// console.log(JSON.(res.data));
// console.log(res.data.code);
// that.data.navatarUrl = res.data;
// that.setData({
// avatarUrl:res.data,
// })
// console.log(res.data);
// this.setData({
// register_rule: !0
// })
}
})
// getApp().globalData.userInfo.avatarUrl = avatarUrl
// console.log();
// getApp().core.setStorageSync(getApp().const.USER_INFO.avatar_url, avatarUrl);
},
formSubmit(e){
var userInfo = getApp().getUser();
userInfo.nickname = e.detail.value.nickname;
userInfo.avatar_url = e.detail.value.avatar;
// getApp().getUser() = userInfo;
//开始与服务器进行链接更改用户数据信息
getApp().request({
url: getApp().api.user.users_save,
method: "post",
data: {
nickname: userInfo.nickname,
avatar_url: userInfo.avatar_url,
user_id: userInfo.id,
},
success: function (e) {
getApp().core.hideLoading(), 0 == e.code && getApp().core.showModal({
title: "提示",
content: e.msg,
showCancel: !1,
success: function (e) {
wx.navigateTo({
url: '/pages/user/user',
})
}
}), 1 == e.code && t.showToast({
title: e.msg
})
}
})
},
/**
* 生命周期函数--监听页面加载
*/
// onLoad(options) {
// getApp().page.onLoad(this, e)
// wx.onThemeChange((result) => {
// this.setData({
// theme: result.theme
// })
// })
// },
})
index.json
{
"usingComponents": {}
}
index.wxml
<view data-weui-theme="{{theme}}">
<button class="avatar-wrapper" open-type="chooseAvatar" bindchooseavatar="onChooseAvatar">
<image class="avatar" src="{{avatarUrl}}"></image>
</button>
<form catchsubmit="formSubmit">
<view class="row">
<view class="text1">昵称:</view>
<input type="nickname" class="weui-input" name="nickname" placeholder="请输入昵称"/>
<input hidden="true" name="avatar" value="{{avatarUrl}}" />
</view>
<button type="primary" style="margin-top: 40rpx;margin-bottom: 20rpx;" form-type="submit">提交</button>
</form>
</view>
index.wxss
.avatar-wrapper {
padding: 0;
width: 56px !important;
border-radius: 8px;
margin-top: 40px;
margin-bottom: 40px;
background-color: #fff;
}
.avatar {
display: block;
width: 56px;
height: 56px;
}
.container {
display: flex;
}
.row{
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
display: flex;
align-items: center;
height: 80rpx;
padding-left: 20rpx;
}
.text1{
flex: 2;
}
.weui-input{
flex: 6;
}
接口自定义
小程序接口自定义(user/users_save):
所在目录
项目名称\core\api.js
代码展示
备注:Yii中API的接口方法格式为:action+驼峰命名法的英文,方法示例:actionUsersSave。
users_save: _api_root + "user/users-save",
后端API接口位置
项目名称\modules\api\controllers
错误位置
项目名称\assets\modules\api\controllers
后端接口方法(Yii框架)
方法一位置(控制器)
项目名称\modules\api\controllers\UserController.php:
//保存用户数据信息
public function actionUsersSave()
{
$form = new UserForm();
$form->attributes = \Yii::$app->request->post();
// $avatar_url = \Yii::$app->request->post('avatar_url');
$form->store_id = $this->store->id;
$form->user_id = \Yii::$app->user->id;
return new BaseApiResponse($form->saveUserNewInfo());
}
方法二位置(Model层)
项目名称\modules\api\models\UserForm.php:
/**
* @param $code
* @return mixed
* 更新用户数据信息
*/
public function saveUserNewInfo(){
//查询用户数据信息是否存在
$user = User::findOne(['id' => $this->user_id]);
$nickname = \Yii::$app->request->post('nickname');
$avatar_url = \Yii::$app->request->post('avatar_url');
if($user){
if(empty($nickname) || empty($avatar_url)){
return [
'code'=>1,
'msg'=>'数据填写不全,请填写完整后重试!'
];
}else{
$user->avatar_url = $avatar_url;
$user->nickname = $nickname;
$user->save();
return [
'code'=>0,
'msg'=>'保存成功!'
];
}
}else{
return [
'code'=>1,
'msg'=>'暂未查询到此用户!'
];
}
}
二次修改限制
更新之后的用户则无需第二次的头像昵称信息的修改操作:
代码完整展示:
wxml部分
<block wx:if='{{user_info.is_change == 1}}'>
<view class='flex-grow-0' bindtap="get_user_info">
<image class='avatar' src='{{user_info.avatar_url}}'></image>
</view>
<view class='flex-grow-1' bindtap="get_user_info">
<text class='user-name'>{{user_info.nickname}}</text>
<view bindtap='member' class='user-level flex-row'>
<view class='level-name flex-y-bottom'>
<image src='{{__wxapp_img.user.level.url}}'></image>
<view class='flex-y-center' style='height:100%;'>{{ (user_info.level_name || "普通用户") }}</view>
</view>
</view>
</view>
</block>
<block wx:else>
<view class='flex-grow-0'>
<image class='avatar' src='{{user_info.avatar_url}}'></image>
</view>
<view class='flex-grow-1'>
<text class='user-name'>{{user_info.nickname}}</text>
<view bindtap='member' class='user-level flex-row'>
<view class='level-name flex-y-bottom'>
<image src='{{__wxapp_img.user.level.url}}'></image>
<view class='flex-y-center' style='height:100%;'>{{ (user_info.level_name || "普通用户") }}</view>
</view>
</view>
</view>
</block>
js部分
if(o.data.user_info.nickname === '微信用户'){
o.data.user_info.is_change = 1;
}else{
o.data.user_info.is_change = 0;
}
图片上传服务器服务器端代码
actionUploadImage方法
在\modules\api\controllers\DefaultController.php文件中
public function actionUploadImage()
{
$form = new UploadForm();
$upload_config = UploadConfig::findOne(['store_id' => $this->store->id]);
$form->upload_config = $upload_config;
return new BaseApiResponse($form->saveImage('thumb'));
}
saveImage方法
在\models\UploadForm.php文件中
public function saveImageOld($name = null)
{
if (!$name) {
foreach ($_FILES as $_name => $file) {
$name = $_name;
}
}
if (!$name) {
$name = 'image';
}
$this->image = UploadedFile::getInstanceByName($name);
if (!$this->validate()) {
return $this->errors;
}
$allow_type = ['jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp',];
if (!in_array($this->image->extension, $allow_type)) {
return [
'code' => 1,
'msg' => '上传文件格式不正确,请上传' . implode('/', $allow_type) . '格式的图片',
];
}
$fileMd5 = md5_file($this->image->tempName);
$saveName = $fileMd5 . '.' . $this->image->extension;
$saveDir = '/web/temuploads/image/' . substr($saveName, 0, 2) . '/';
$res = $this->saveFile($this->image->tempName, $saveDir, $saveName);
if ($res['code'] == 0) {
$res['data']['extension'] = $this->image->extension;
$res['data']['type'] = $this->getFileType($this->image->extension);
$res['data']['size'] = $this->image->size;
}
$this->saveData($res);
return $res;
}
中间问题记录
1.wx.uploadFile方法中的url地址如果不填写正确的话会出现错误
onChooseAvatar(e) {
const { avatarUrl } = e.detail
this.setData({
avatarUrl:avatarUrl,
})
// const { avatarUrl } = e.detail
// this.setData({
// avatarUrl,
// })
let that = this
wx.uploadFile({
url: getApp().api.default.upload_image,//着重强调此项
// url:t.api.default.upload_image,
filePath: that.data.avatarUrl,
name: 'image',
success(res) {
// console.log(res);
if(res.statusCode == 200){
// wx.showToast({
// title: '网络异常,上传失败请重试!'
// })
var show_images = JSON.parse(res.data);
if(show_images.code == 0){
that.setData({//已经let that = this了,所以就不需要再使用this.setData了,使用that.setData
avatarUrl:show_images.data.url,
})
}else{
wx.showToast({
title: '网络异常,上传失败请重试!'
})
}
}else{
wx.showToast({
title: '网络异常,上传失败请重试!'
})
}
// console.log(JSON.parse(res.data));
// console.log(JSON.(res.data));
// console.log(res.data.code);
// that.data.navatarUrl = res.data;
// that.setData({
// avatarUrl:res.data,
// })
// console.log(res.data);
// this.setData({
// register_rule: !0
// })
}
})
// getApp().globalData.userInfo.avatarUrl = avatarUrl
// console.log();
// getApp().core.setStorageSync(getApp().const.USER_INFO.avatar_url, avatarUrl);
},
2.上传成功后一定要使用如下方法将头像链接进行重新赋值,否则依然未手机本地照片路径,无法与服务器进行链接
that.setData({
avatarUrl:show_images.data.url,
})
3.可以使用缓存的照片路径在修改界面默认显示,不显示则使用默认头像(使用三元运算符)
4.wx.uploadFile方法中的name属性一定要与服务器接口的名字一致,否则报错
onChooseAvatar(e) {
const { avatarUrl } = e.detail
this.setData({
avatarUrl:avatarUrl,
})
// const { avatarUrl } = e.detail
// this.setData({
// avatarUrl,
// })
let that = this
wx.uploadFile({
url: getApp().api.default.upload_image,
// url:t.api.default.upload_image,
filePath: that.data.avatarUrl,
name: 'image', //着重强调此项
success(res) {
// console.log(res);
if(res.statusCode == 200){
// wx.showToast({
// title: '网络异常,上传失败请重试!'
// })
var show_images = JSON.parse(res.data);
if(show_images.code == 0){
that.setData({//已经let that = this了,所以就不需要再使用this.setData了,使用that.setData
avatarUrl:show_images.data.url,
})
}else{
wx.showToast({
title: '网络异常,上传失败请重试!'
})
}
}else{
wx.showToast({
title: '网络异常,上传失败请重试!'
})
}
// console.log(JSON.parse(res.data));
// console.log(JSON.(res.data));
// console.log(res.data.code);
// that.data.navatarUrl = res.data;
// that.setData({
// avatarUrl:res.data,
// })
// console.log(res.data);
// this.setData({
// register_rule: !0
// })
}
})
// getApp().globalData.userInfo.avatarUrl = avatarUrl
// console.log();
// getApp().core.setStorageSync(getApp().const.USER_INFO.avatar_url, avatarUrl);
},
5.JSON.parse可解析json化的数据
var show_images = JSON.parse(res.data);