mirror of
https://gitee.com/zongzhige/shopxo.git
synced 2024-11-30 02:49:03 +08:00
微信
This commit is contained in:
parent
3902f2ae2d
commit
8d1f68a61c
@ -102,6 +102,45 @@ class User extends Common
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信小程序获取用户授权
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-11-06
|
||||
* @desc description
|
||||
*/
|
||||
public function WechatUserAuth()
|
||||
{
|
||||
$result = (new \base\Wechat('111', '222'))->GetAuthSessionKey(input('authcode'));
|
||||
if($result !== false)
|
||||
{
|
||||
return DataReturn('授权登录成功', 0, $result);
|
||||
}
|
||||
return DataReturn('授权登录失败', -100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信小程序获取用户信息
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-11-06
|
||||
* @desc description
|
||||
*/
|
||||
public function WechatUserInfo()
|
||||
{
|
||||
$result = (new \base\Wechat('100', '200'))->DecryptData(R('encrypted_data'), input('iv'), input('openid'));
|
||||
|
||||
if(is_array($result))
|
||||
{
|
||||
$result['openid'] = $result['openId'];
|
||||
$result['referrer']= isset($this->data_post['referrer']) ? intval($this->data_post['referrer']) : 0;
|
||||
return UserService::AuthUserProgram($result, 'wechat_openid');
|
||||
}
|
||||
return DataReturn('获取用户信息失败', -100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 百度小程序获取用户信息
|
||||
* @author Devil
|
||||
|
238
extend/base/Wechat.php
Normal file
238
extend/base/Wechat.php
Normal file
@ -0,0 +1,238 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2011~2018 http://shopxo.net All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Devil
|
||||
// +----------------------------------------------------------------------
|
||||
namespace base;
|
||||
|
||||
/**
|
||||
* 微信驱动
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @date 2018-06-28
|
||||
* @desc 支持所有文件存储到硬盘
|
||||
*/
|
||||
class Wechat
|
||||
{
|
||||
// appid
|
||||
private $_appid;
|
||||
|
||||
// appsecret
|
||||
private $_appsecret;
|
||||
|
||||
/**
|
||||
* [__construct 构造方法]
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @datetime 2017-12-30T18:04:05+0800
|
||||
* @param [string] $app_id [应用appid]
|
||||
* @param [string] $app_secret [应用密钥]
|
||||
*/
|
||||
public function __construct($app_id, $app_secret)
|
||||
{
|
||||
$this->_appid = $app_id;
|
||||
$this->_appsecret = $app_secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* [DecryptData 检验数据的真实性,并且获取解密后的明文]
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @datetime 2017-12-30T18:20:53+0800
|
||||
* @param [string] $encrypted_data [加密的用户数据]
|
||||
* @param [string] $iv [与用户数据一同返回的初始向量]
|
||||
* @param [string] $openid [解密后的原文]
|
||||
* @return [array|string] [成功返回用户信息数组, 失败返回错误信息]
|
||||
*/
|
||||
public function DecryptData($encrypted_data, $iv, $openid)
|
||||
{
|
||||
// 登录授权session
|
||||
$login_key = 'wechat_user_login_'.$openid;
|
||||
$session_data = GS($login_key);
|
||||
if($session_data === false)
|
||||
{
|
||||
return 'session key不存在';
|
||||
}
|
||||
$aes_key = base64_decode($session_data['session_key']);
|
||||
|
||||
if(strlen($iv) != 24)
|
||||
{
|
||||
return 'iv长度错误';
|
||||
}
|
||||
$aes_iv = base64_decode($iv);
|
||||
|
||||
$aes_cipher = base64_decode($encrypted_data);
|
||||
$result = openssl_decrypt($aes_cipher, "AES-128-CBC", $aes_key, 1, $aes_iv);
|
||||
$data = json_decode($result, true);
|
||||
if($data == NULL)
|
||||
{
|
||||
return '数据解密失败';
|
||||
}
|
||||
if($data['watermark']['appid'] != $this->_appid )
|
||||
{
|
||||
return 'appid不匹配';
|
||||
}
|
||||
|
||||
// 缓存存储
|
||||
$data_key = 'wechat_user_info_'.$openid;
|
||||
SS($data_key, $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* [GetAuthSessionKey 根据授权code获取 session_key 和 openid]
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @datetime 2017-12-30T18:20:53+0800
|
||||
* @param [string] $authcode [用户授权码]
|
||||
* @return [string|boolean] [失败false, 成功返回appid|]
|
||||
*/
|
||||
public function GetAuthSessionKey($authcode)
|
||||
{
|
||||
// 请求获取session_key
|
||||
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$this->_appid.'&secret='.$this->_appsecret.'&js_code='.$authcode.'&grant_type=authorization_code';
|
||||
$result = $this->HttpRequestGet($url);
|
||||
if(!empty($result['openid']))
|
||||
{
|
||||
// 从缓存获取用户信息
|
||||
$key = 'wechat_user_login_'.$result['openid'];
|
||||
|
||||
// 缓存存储
|
||||
SS($key, $result);
|
||||
return $result['openid'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* [MiniQrCodeCreate 二维码创建]
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @datetime 2018-01-02T19:53:10+0800
|
||||
* @param [array] $params [输入参数]
|
||||
* @return [string] [成功返回文件流, 失败则空]
|
||||
*/
|
||||
public function MiniQrCodeCreate($params)
|
||||
{
|
||||
// 参数校验
|
||||
if(empty($params['path']))
|
||||
{
|
||||
return '页面地址不能为空';
|
||||
}
|
||||
$params['width'] = empty($params['width']) ? 1000 : intval($params['width']);
|
||||
|
||||
// 获取access_token
|
||||
$access_token = $this->GetMiniAccessToken();
|
||||
if($access_token === false)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
// 网络请求
|
||||
$url = 'https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token='.$access_token;
|
||||
$data = [
|
||||
'path' => $params['path'],
|
||||
'width' => $params['width'],
|
||||
];
|
||||
return $this->HttpRequestPost($url, json_encode($data), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* [GetMiniAccessToken 获取access_token]
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @datetime 2018-01-02T19:53:42+0800
|
||||
*/
|
||||
private function GetMiniAccessToken()
|
||||
{
|
||||
// 缓存key
|
||||
$key = $this->_appid.'_access_token';
|
||||
$result = GS($key);
|
||||
if($result !== false)
|
||||
{
|
||||
if($result['expires_in'] > time())
|
||||
{
|
||||
return $result['access_token'];
|
||||
}
|
||||
}
|
||||
|
||||
// 网络请求
|
||||
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->_appid.'&secret='.$this->_appsecret;
|
||||
$result = $this->HttpRequestGet($url);
|
||||
if(!empty($result['access_token']))
|
||||
{
|
||||
// 缓存存储
|
||||
$result['expires_in'] += time();
|
||||
SS($key, $result);
|
||||
return $result['access_token'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* [HttpRequestGet get请求]
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @datetime 2018-01-03T19:21:38+0800
|
||||
* @param [string] $url [url地址]
|
||||
* @return [array] [返回数据]
|
||||
*/
|
||||
private function HttpRequestGet($url)
|
||||
{
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 500);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
|
||||
$res = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
return json_decode($res, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* [HttpRequestPost curl模拟post]
|
||||
* @author Devil
|
||||
* @blog http://gong.gg/
|
||||
* @version 1.0.0
|
||||
* @datetime 2017-09-25T09:10:46+0800
|
||||
* @param [string] $url [请求地址]
|
||||
* @param [array] $data [发送的post数据]
|
||||
* @param [array] $is_parsing [是否需要解析数据]
|
||||
* @return [array] [返回的数据]
|
||||
*/
|
||||
private function HttpRequestPost($url, $data, $is_parsing = true)
|
||||
{
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, 500);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
|
||||
$res = curl_exec($curl);
|
||||
if($is_parsing === true)
|
||||
{
|
||||
return json_decode($reponse, true);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
@ -205,18 +205,6 @@ App({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取本系统用户信息
|
||||
*/
|
||||
GetMyUserInfo() {
|
||||
var user = this.GetUserCacheInfo();
|
||||
if (user == false) {
|
||||
return null;
|
||||
} else {
|
||||
return user.my_user || null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 从缓存获取用户信息
|
||||
*/
|
||||
@ -225,9 +213,6 @@ App({
|
||||
if ((user || null) == null) {
|
||||
return false;
|
||||
}
|
||||
if ((user.my_user || null) == null) {
|
||||
user.my_user = null;
|
||||
}
|
||||
return user;
|
||||
},
|
||||
|
||||
@ -258,17 +243,21 @@ App({
|
||||
// 请求授权接口
|
||||
wx.getSetting({
|
||||
success(res) {
|
||||
console.log('app.js 授权部分');
|
||||
wx.navigateTo({
|
||||
url: "/pages/login/login"
|
||||
});
|
||||
if (!res.authSetting['scope.userInfo']) {
|
||||
wx.authorize({
|
||||
scope: 'scope.userInfo',
|
||||
success() {
|
||||
$this.user_auth_login(object, method);
|
||||
},
|
||||
fail: (e) => {
|
||||
wx.hideLoading();
|
||||
$this.showToast('授权失败');
|
||||
}
|
||||
});
|
||||
// wx.authorize({
|
||||
// scope: 'scope.userInfo',
|
||||
// success() {
|
||||
// $this.user_auth_login(object, method);
|
||||
// },
|
||||
// fail: (e) => {
|
||||
// wx.hideLoading();
|
||||
// $this.showToast('授权失败');
|
||||
// }
|
||||
// });
|
||||
} else {
|
||||
$this.user_auth_login(object, method);
|
||||
}
|
||||
@ -314,7 +303,7 @@ App({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
wx.request({
|
||||
url: $this.get_request_url('GetWechatUserLogin', 'User'),
|
||||
url: $this.get_request_url('WechatUserAuth', 'user'),
|
||||
method: 'POST',
|
||||
data: { authcode: res.code },
|
||||
dataType: 'json',
|
||||
@ -358,7 +347,7 @@ App({
|
||||
success: function (res) {
|
||||
// 远程解密数据
|
||||
wx.request({
|
||||
url: $this.get_request_url('GetWechatUserInfo', 'User'),
|
||||
url: $this.get_request_url('WechatUserInfo', 'user'),
|
||||
method: 'POST',
|
||||
data: { encrypted_data: res.encryptedData, iv: res.iv, openid: openid },
|
||||
dataType: 'json',
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"pages": [
|
||||
"pages": ["pages/cart/cart",
|
||||
"pages/index/index",
|
||||
"pages/goods-category/goods-category",
|
||||
"pages/cart/cart",
|
||||
|
||||
"pages/user/user",
|
||||
"pages/web-view/web-view",
|
||||
"pages/login/login",
|
||||
|
@ -1,7 +1,5 @@
|
||||
{
|
||||
"enablePullDownRefresh": true,
|
||||
"usingComponents": {
|
||||
"list-item": "mini-antui/es/list/list-item/index",
|
||||
"swipe-action": "mini-antui/es/swipe-action/index"
|
||||
}
|
||||
}
|
@ -1,41 +1,39 @@
|
||||
<view wx:if="{{data_list.length > 0}}" class="page">
|
||||
<view wx:for="{{data_list}}" class="goods-item oh bg-white">
|
||||
<swipe-action index="{{index}}" restore="{{swipe_index === null || swipe_index !== index}}" right="{{item.right}}" onRightItemClick="right_item_event" onSwipeStart="swipe_start_event" extra="{{index}}">
|
||||
<!-- 选择 -->
|
||||
<view bindtap="selectedt_event" data-type="node" data-index="{{index}}" class="fl selected">
|
||||
<image wx:if="{{(item.selected || false)}}" class="icon" src="/images/default-select-active-icon.png" mode="widthFix" />
|
||||
<image wx:else class="icon" src="/images/default-select-icon.png" mode="widthFix" />
|
||||
<view wx:for="{{data_list}}" wx:key="key" class="goods-item oh bg-white">
|
||||
<!-- 选择 -->
|
||||
<view bindtap="selectedt_event" data-type="node" data-index="{{index}}" class="fl selected">
|
||||
<image wx:if="{{(item.selected || false)}}" class="icon" src="/images/default-select-active-icon.png" mode="widthFix" />
|
||||
<image wx:else class="icon" src="/images/default-select-icon.png" mode="widthFix" />
|
||||
</view>
|
||||
|
||||
<view class="bg-white items">
|
||||
<!-- 图片/链接 -->
|
||||
<navigator url="/pages/goods-detail/goods-detail?goods_id={{item.goods_id}}">
|
||||
<image class="goods-image fl" src="{{item.images}}" mode="aspectFill" />
|
||||
</navigator>
|
||||
|
||||
<!-- 基础 -->
|
||||
<view class="goods-base">
|
||||
<view class="goods-title multi-text">{{item.title}}
|
||||
</view>
|
||||
<block wx:if="{{item.spec != null}}">
|
||||
<view class="goods-attribute cr-888" wx:for="{{item.spec}}" wx:for-item="spec">{{spec.type}}:{{spec.value}}</view>
|
||||
</block>
|
||||
</view>
|
||||
<!-- 数量 -->
|
||||
<view class="number-content tc oh">
|
||||
<view bindtap="goods_buy_number_event" class="number-submit tc cr-888 fl" data-index="{{index}}" data-type="0">-</view>
|
||||
<input onBlur="goods_buy_number_blur" class="tc cr-888 fl" type="number" value="{{item.stock}}" data-index="{{index}}" />
|
||||
<view bindtap="goods_buy_number_event" class="number-submit tc cr-888 fl" data-index="{{index}}" data-type="1">+</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-white items">
|
||||
<!-- 图片/链接 -->
|
||||
<navigator url="/pages/goods-detail/goods-detail?goods_id={{item.goods_id}}">
|
||||
<image class="goods-image fl" src="{{item.images}}" mode="aspectFill" />
|
||||
</navigator>
|
||||
|
||||
<!-- 基础 -->
|
||||
<view class="goods-base">
|
||||
<view class="goods-title multi-text">{{item.title}}
|
||||
</view>
|
||||
<block wx:if="{{item.spec != null}}">
|
||||
<view class="goods-attribute cr-888" wx:for="{{item.spec}}" wx:for-item="spec">{{spec.type}}:{{spec.value}}</view>
|
||||
</block>
|
||||
</view>
|
||||
<!-- 数量 -->
|
||||
<view class="number-content tc oh">
|
||||
<view bindtap="goods_buy_number_event" class="number-submit tc cr-888 fl" data-index="{{index}}" data-type="0">-</view>
|
||||
<input onBlur="goods_buy_number_blur" class="tc cr-888 fl" type="number" value="{{item.stock}}" data-index="{{index}}" />
|
||||
<view bindtap="goods_buy_number_event" class="number-submit tc cr-888 fl" data-index="{{index}}" data-type="1">+</view>
|
||||
</view>
|
||||
|
||||
<!-- 价格 -->
|
||||
<view class="oh goods-price">
|
||||
<text class="sales-price">¥{{item.price}}</text>
|
||||
<text wx:if="{{item.original_price > 0}}" class="original-price">¥{{item.original_price}}</text>
|
||||
<text class="buy-number cr-888">x{{item.stock}}</text>
|
||||
</view>
|
||||
<!-- 价格 -->
|
||||
<view class="oh goods-price">
|
||||
<text class="sales-price">¥{{item.price}}</text>
|
||||
<text wx:if="{{item.original_price > 0}}" class="original-price">¥{{item.original_price}}</text>
|
||||
<text class="buy-number cr-888">x{{item.stock}}</text>
|
||||
</view>
|
||||
</swipe-action>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作导航 -->
|
||||
|
@ -20,9 +20,19 @@ Page({
|
||||
wx.setNavigationBarTitle({title: '手机绑定'});
|
||||
|
||||
// 设置用户信息
|
||||
this.setData({params: option, user: app.GetUserCacheInfo()});
|
||||
this.setData({
|
||||
params: option,
|
||||
user: app.GetUserCacheInfo() || null
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 登录授权事件
|
||||
*/
|
||||
get_user_info_event(e) {
|
||||
console.log(e, e.detail.userInfo)
|
||||
}
|
||||
|
||||
/**
|
||||
* 输入手机号码事件
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
<view class="content">
|
||||
<view wx:if="{{user != null}}" class="content">
|
||||
<form bindsubmit="formSubmit">
|
||||
<input type="number" placeholder="输入手机号码" maxlength="11" name="mobile" onInput="bind_key_input" class="mobile" />
|
||||
<view class="code clearfix">
|
||||
@ -7,4 +7,9 @@
|
||||
</view>
|
||||
<button type="default" formType="submit" hover-class="none" plain loading="{{form_submit_loading}}" disabled="{{form_submit_loading}}" class="submit {{form_submit_loading ? 'my-btn-gray' : 'my-btn-default'}}">确认绑定</button>
|
||||
</form>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{user == null}}" class="wx-login tc">
|
||||
<view class="cr-888 fs-12">确认登录授权,为您提供更优质的服务</view>
|
||||
<button type="primary" size="mini" open-type="getUserInfo" bindgetuserinfo="get_user_info_event">授权登录</button>
|
||||
</view>
|
||||
|
@ -46,4 +46,14 @@ page{
|
||||
bottom: 34rpx;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
}
|
||||
|
||||
/**
|
||||
授权登录
|
||||
*/
|
||||
.wx-login {
|
||||
padding-top: 30%;
|
||||
}
|
||||
.wx-login button {
|
||||
margin-top: 30rpx;
|
||||
}
|
Loading…
Reference in New Issue
Block a user