前端注意,这里一定是直接获取的code。这里的code很容易混淆哦。
一定是getPhoneNumber的
getPhoneNumber(e) {
// 1. 防止重复点击
if (this.data.isGettingPhone) return;
// 2. 检查用户是否授权
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
wx.showToast({ title: '授权失败', icon: 'none' });
return;
}
// 3. 设置加载状态
this.setData({ isGettingPhone: true });
const encryptedData = e.detail.encryptedData;
const iv = e.detail.iv;
const user_id = this.data.userInfo.user_id;
const phoneCode = e.detail.code;
// 5. 立即发送请求(不要延迟)
App._post_form('user/getphone', {
encryptedData: encryptedData,
iv: iv,
code: phoneCode, // ← 全新 code
user_id: user_id
}, (result) => {
this.setData({ isGettingPhone: false });
if (result.code === 1) {
wx.showToast({ title: '绑定成功', icon: 'success' });
this.setData({
hasPhone: true,
PhoneNumber: result.data.phoneNumber
});
} else {
wx.showToast({ title: result.msg || '操作失败', icon: 'none' });
}
}, () => {
// 请求失败回调
this.setData({ isGettingPhone: false });
wx.showToast({ title: '网络错误', icon: 'none' });
});
},
data里加:isGettingPhone: false,
前端:
<button
class="phone-btn {{hasPhone ? 'btn-success' : ''}}"
open-type="getPhoneNumber"
bindgetphonenumber="getPhoneNumber"
loading="{{isGettingPhone}}"
>
{{ hasPhone ? '已授权' : '点击授权手机号' }}
</button>
public function getphone()
{
$data = $this->request->param();
$code = $data['code'] ?? null;
$user_id = $data['user_id'] ?? null;
if (!$code || !$user_id) {
return $this->renderError('参数缺失');
}
// 1. 获取小程序配置
$wxapp_id = (string) input('wxapp_id', '');
$wxConfig = Db::name('wxapp')->where('wxapp_id', $wxapp_id)->find();
if (!$wxConfig) {
return $this->renderError('小程序配置不存在');
}
$params = [
'appid' => $wxConfig['app_id'],
'secret' => $wxConfig['app_secret'],
'grant_type' => 'client_credential'
];
$tokenUrl = 'https://api.weixin.qq.com/cgi-bin/token?' . http_build_query($params);
// 3. 发送 GET 请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $tokenUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$tokenRes = json_decode($response, true);
// 4. 严格校验响应
if ($httpCode !== 200 || !isset($tokenRes['access_token']) || !is_string($tokenRes['access_token'])) {
return $this->renderError('服务初始化失败');
}
$accessToken = $tokenRes['access_token'];
$headers = [
'Content-Type: application/json; charset=utf-8',
'Accept: application/json'
];
$url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $accessToken;
$requestBody = json_encode(['code' => $code], JSON_UNESCAPED_UNICODE);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
$phoneRes = json_decode($response, true);
// 4. 处理结果
if (!is_array($phoneRes)) {
return $this->renderError('接口返回格式错误');
}
// 5. 成功拿到手机号
$phoneNumber = $phoneRes['phone_info']['phoneNumber'] ?? '';
if (!$phoneNumber) {
return $this->renderError('未返回手机号');
}
// 6. 保存到数据库
$model = new UserModel;
if (!$model->editPhone($user_id, $phoneNumber)) {
return $this->renderError($model->getError() ?: '保存失败');
}
return $this->renderSuccess('操作成功', ['phoneNumber' => $phoneNumber]);
}