where('user_id', $user_id)
->field([
'password',
'user_id',
'openid',
'frozen'
])
->find();
if (empty($toUserInfo)) {
throw new \Exception('用户不存在');
}
if ($userInfo['species'] setInc('species', $num);
Users::where('user_id', $userInfo['user_id'])->setDec('species', $num);
Users::where('user_id', $userInfo['user_id'])->setInc('species_give', $num);
$tospec = new UserSpecies();
$toid = $tospec->add($user_id, 2, 1, $num, "获得好友赠送鸡蛋");
$fromspec = new UserSpecies();
$fromid = $fromspec->add($userInfo['user_id'], 3, 2, $num, "赠送给好友鸡蛋");
$guanlian = new UserGive();
$guanlian->add($toid, $fromid);
Db::commit();
return [
'code' => ReturnCode::SUCCESS_CODE,
'msg' => '登录成功',
'data' => ''
];
} catch (\Exception $e) {
Db::rollback();
Log::write('会员登录失败: ' . $e->getMessage(), 'error');
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => '会员登录失败' . $e->getMessage()
];
}
}
/**
* 用户登录
*
* @throws \Exception
*/
public function login()
{
$account = Request::param('account'); // 微信小程序返回用户信息
$password = Request::param('password'); // 微信小程序返回用户信息
Db::startTrans();
try {
$userModel = new Users();
$userInfo = $userModel->getUserByAccount($account, 1, [
'password',
'user_id',
'openid',
'frozen'
]);
if (empty($userInfo)) {
throw new \Exception('账号不存在');
}
if ($userInfo['password'] != md5($password)) {
throw new \Exception('密码不正确');
}
if ($userInfo['frozen'] != 1) {
throw new \Exception('用户已被冻结');
}
$getToken = $this->setToken($userInfo['user_id'], 1);
$openid = $userInfo['openid'];
Db::commit();
return [
'code' => ReturnCode::SUCCESS_CODE,
'msg' => '登录成功',
'data' => [
'openid' => $openid,
'token' => $getToken
]
];
} catch (\Exception $e) {
Db::rollback();
Log::write('会员登录失败: ' . $e->getMessage(), 'error');
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => '会员登录失败' . $e->getMessage()
];
}
}
/**
* 用户注册
*
* @throws \Exception
*/
public function register()
{
$account = Request::param('account'); // 微信小程序返回用户信息
$password = Request::param('password'); // 微信小程序返回用户信息
$rpassword = Request::param('rpassword'); // 微信小程序返回用户信息
Db::startTrans();
try {
if (! isStringNumberLessThan($account)) {
throw new \Exception('请输入正确得电话号码格式,11位电话号码');
}
if (strlen($password) > 25) {
throw new \Exception('密码长度最长25个字符');
}
if ($password != $rpassword) {
throw new \Exception('两次密码不一致');
}
$userModel = new Users();
$userInfo = $userModel->getUserByAccount($account, 1, [
'password',
'user_id',
'openid'
]);
if (! empty($userInfo)) {
throw new \Exception('账号已存在');
}
$ip = $_SERVER["REMOTE_ADDR"];
$avatarUrl = 'https://thirdwx.qlogo.cn/mmopen/vi_32/4MwaJwuQl7orrLGWacxPBw3VLJUcGad8QHYiaZ5NE3LhrvIVzDRF7AJuVXtlSCtEx79Jbjibe4OlvibTUgoEk9MKA/132';
$user = [
'account' => $account, // 用户账号
'password' => md5($password), // 用户头像url
'nickname' => generateChineseNickname(4), // 用户昵称
'head' => $avatarUrl, // 用户头像url
'session_key' => '', // 用户sessionKey
'unionid' => '',
'openid' => '',
'oauth' => 'acc',
'reg_ip' => $ip, // 注册IP
'login_ip' => $ip, // 登录IP
'reg_time' => time(), // 注册时间
'login_time' => time()
]; // 登陆时间
$userInfo = $userModel->addUserDataInfo($user);
$getToken = $this->setToken($userInfo['user_id'], 2);
$openid = $userInfo['openid'];
Db::commit();
return [
'code' => ReturnCode::SUCCESS_CODE,
'msg' => '登录成功',
'data' => [
'openid' => $openid,
'token' => $getToken
]
];
} catch (\Exception $e) {
Db::rollback();
Log::write('会员登录失败: ' . $e->getMessage(), 'error');
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => '会员登录失败' . $e->getMessage()
];
}
}
protected function TestEntry()
{
$openid = Request::param('openid'); // 微信小程序返回用户信息
Db::startTrans();
try {
if (empty($openid)) {
$user_openid = 'oBhyo4slnVBdThGdOoMsw3n11l';
}
$userModel = new Users();
$userInfo = $userModel->getUserByAccount($openid, 2);
if ($userInfo) {
if (! isset($userInfo) || empty($userInfo)) {
throw new \Exception('用户不存在');
}
if ($userInfo['frozen'] != 1) {
throw new \Exception('用户已被冻结');
}
$getToken = $this->setToken($userInfo['user_id'], 1);
$openid = $userInfo['openid'];
} else {
$ip = $_SERVER["REMOTE_ADDR"];
$nickname = '测试';
$avatarUrl = 'https://thirdwx.qlogo.cn/mmopen/vi_32/4MwaJwuQl7orrLGWacxPBw3VLJUcGad8QHYiaZ5NE3LhrvIVzDRF7AJuVXtlSCtEx79Jbjibe4OlvibTUgoEk9MKA/132';
$user = [
'nickname' => $nickname, // 用户昵称
'head' => $avatarUrl, // 用户头像url
'openid' => $openid, // 用户openId
'session_key' => '', // 用户sessionKey
'unionid' => '',
'oauth' => 'cs',
'reg_ip' => $ip, // 注册IP
'login_ip' => $ip, // 登录IP
'reg_time' => time(), // 注册时间
'login_time' => time()
]; // 登陆时间
$userInfo = $userModel->addUserDataInfo($user);
$getToken = $this->setToken($userInfo['user_id'], 2);
$openid = $userInfo['openid'];
}
Db::commit();
return [
'code' => ReturnCode::SUCCESS_CODE,
'msg' => '登录成功',
'data' => [
'token' => $getToken,
'openid' => $openid
]
];
} catch (\Exception $e) {
Db::rollback();
Log::write('会员登录失败: ' . $e->getMessage(), 'error');
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => '会员登录失败'
];
}
}
/**
* 微信抖音登录
*
* @param string $oauth
* 'dy'|'wx'
* @return array
*/
protected function wxLogin($oauth = "wx")
{
$code = Request::param('code'); // 微信返回code
switch ($oauth) {
case 'wx':
$logsList = $this->weixin_s(zf_cache("web_info.wxAppid"), zf_cache("web_info.dyAppSecret"), $code);
break;
case 'dy':
$logsList = $this->dY_Info(zf_cache("web_info.dyAppid"), zf_cache("web_info.dyAppSecret"), $code);
break;
case 'wxapp':
$logsList = $this->wxOauth2(zf_cache("web_info.appid"), zf_cache("web_info.appsecret"), $code);
break;
case 'wxh5':
$logsList = $this->wxOauth2(zf_cache("web_info.h5Appid"), zf_cache("web_info.h5AppSecret"), $code);
break;
default:
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => '平台选择错误'
];
}
if (isset($logsList->errcode) && ! empty($logsList['errcode'])) {
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => "接口调用错误:" . $logsList['errmsg']
];
}
$unionid = "";
$session_key = "";
// 防止第二次访问动态链接报错
// 判断是否获取到当前用户的openid
if (! isset($logsList->openid) || empty($logsList->openid)) {
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => '未获取到openid'
];
}
$open_id = $logsList->openid;
if (isset($logsList->unionid) && ! empty($logsList->unionid)) {
$unionid = $logsAccessToken->unionid;
}
if (isset($logsList->session_key) && ! empty($logsList->session_key)) {
$session_key = $logsList->session_key;
}
if (isset($logsList->access_token) && ! empty($logsList->access_token)) {
$session_key = $logsList->access_token;
}
Db::startTrans();
try {
$userModel = new Users();
// 判断用户是否存在
$userInfo = $userModel->getUserByAccount($open_id, 2);
// 用户不存在,创建用户
if (empty($userInfo)) {
$nickname = "";
$avatarUrl = "";
switch ($oauth) {
case 'wx':
case 'dy':
$user_info = Request::param('user_info'); // 微信小程序返回用户信息
if (! isset($user_info) || empty($user_info)) {
throw new \Exception('未获取到user_info');
}
if (isset($user_info->nickName) && ! empty($user_info->nickName)) {
$nickname = $this->emoji_encode($user_info['nickName']);
}
if (isset($user_info->avatarUrl) && ! empty($user_info->avatarUrl)) {
$avatarUrl = $user_info['avatarUrl'];
}
break;
case 'wxapp':
case 'wxh5':
$user_info = $this->wxUserInfo($logsList->access_token, $logsList->openid);
if (isset($user_info->errcode) && ! empty($user_info['errcode'])) {
throw new \Exception("接口调用错误:" . $user_info['errmsg']);
}
if (isset($user_info->nickname) && ! empty($user_info->nickname)) {
$nickname = $this->emoji_encode($user_info->nickname);
}
if (isset($user_info->headimgurl) && ! empty($user_info->headimgurl)) {
$avatarUrl = $user_info->headimgurl;
}
break;
default:
throw new \Exception('平台选择错误');
}
$ip = $_SERVER["REMOTE_ADDR"];
$user = [
'nickname' => $nickname, // 用户昵称
'head' => $avatarUrl, // 用户头像url
'openid' => $open_id, // 用户openId
'session_key' => $session_key, // 用户sessionKey
'unionid' => $unionid,
'oauth' => $oauth,
'reg_ip' => $ip, // 注册IP
'login_ip' => $ip, // 登录IP
'reg_time' => time(), // 注册时间
'login_time' => time()
]; // 登陆时间
$userInfo = $userModel->addUserDataInfo($user);
$getToken = $this->setToken($userInfo['user_id'], 2);
} else {
if ($userInfo['frozen'] != 1) {
Db::rollback();
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => '用户已被冻结'
];
}
$getToken = $this->setToken($userInfo['user_id'], 1, $session_key);
$open_id = $userInfo['openid'];
}
Db::commit();
return [
'code' => ReturnCode::SUCCESS_CODE,
'msg' => '登录成功',
'data' => [
'token' => $getToken,
'openid' => $open_id
]
];
} catch (\Exception $e) {
Db::rollback();
Log::write('会员登录失败: ' . $e->getMessage(), 'error');
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => '会员登录失败'
];
}
}
/**
* 会员登录
*
* platform 'wx':
* platform 'dy':
* platform 'wxapp':
* platform 'wxh5':
* platform 'cs':
*
* @return array
*/
public function doLogin()
{
$platform = Request::param('platform'); // 0 测试环境 1 微信小程序 2抖音小程序
if ($platform == "cs") {
return $this->TestEntry();
} else {
return $this->wxLogin($platform);
}
}
/**
*
* @param string $userid
* @param string $type
* 1登录 2注册
* @param string $session_key
* @return string
*/
public function setToken($userid, $type, $session_key = "")
{
$str = $userid . "T" . time();
$token = MD5($str);
$uparray = array(
'token' => $token,
'login_ip' => $_SERVER["REMOTE_ADDR"],
'login_time' => time()
);
if (! empty($session_key)) {
$uparray['session_key'] = $session_key;
}
$str = '登陆成功';
if ($type == 2) {
$str = '注册登陆成功';
}
Users::where(array(
'user_id' => $userid
))->setField($uparray);
$userLogModel = new UsersLog();
$userLogModel->addLog($userid, $type, $str);
return $token;
}
/**
* 微信通过code换取网页授权access_token web与app都是用这个
*
* @param string $app_id
* 公众号的唯一标识
* @param string $app_secret
* 公众号的appsecret
* @param string $code
* 获取的code参数
* @return array 包含以下键的关联数组:
* - access_token: string 访问令牌
* - expires_in: int 令牌过期时间(秒)
* - refresh_token: string 刷新令牌
* - openid: string 用户OpenID
* - scope: string 授权范围 拉取用户信息(需scope为 snsapi_userinfo)
* - is_snapshotuser: int 是否为快照用户(1 表示是,0 表示否)
* - unionid: string 用户UnionID(如果有)
* @throws Exception 如果获取令牌失败,则抛出异常
*/
public function wxOauth2($app_id, $app_secret, $code)
{
// 发送请求,获取用户openid和access_token
$logsList = httpRequest('https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $app_id . '&secret=' . $app_secret . '&code=' . $code . '&grant_type=authorization_code', 'get');
return json_decode($logsList);
}
/**
* 拉取用户信息(需scope为 snsapi_userinfo) web与app都是用这个
*
* @param string $access_token
* @param string $openid
* @return array 包含以下键的关联数组:
* - openid: string 普通用户的标识,对当前开发者账号唯一
* - nickname: string 普通用户昵称
* - sex: int 普通用户性别,1 为男性,2 为女性
* - province: string 普通用户个人资料填写的省份
* - city: string 普通用户个人资料填写的城市
* - country: string 国家,如中国为 CN
* - headimgurl: string 用户头像,最后一个数值代表正方形头像大小(有 0、46、64、96、132 数值可选,0 代表 640*640 正方形头像),用户没有头像时该项为空
* - privilege: string 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
* - unionid: string 用户统一标识。针对一个微信开放平台账号下的应用,同一用户的 unionid 是唯一的。
*/
public function wxUserInfo($access_token, $openid)
{
// 获取当前用户信息 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语
$user_info = httpRequest('https://api.weixin.qq.com/sns/userinfo?access_token=' . $access_token . '&openid=' . $openid . '&lang=zh_CN', 'get');
return json_decode($user_info);
}
/**
*
* @param string $appid
* 公众号的唯一标识
* @param string $secret
* 公众号的appsecret
* @param string $js_code
* 前端传来的code
* @return array 包含以下键的关联数组:
* - errmsg: string 错误信息
* - errcode: int 错误码
* - session_key: string 会话密钥
* - openid: string 用户OpenID
* - unionid: string 用户UnionID(如果有)
* @throws Exception 如果获取令牌失败,则抛出异常
*/
public function weixin_s($appid, $secret, $js_code)
{
$logsList = httpRequest('https://api.weixin.qq.com/sns/jscode2session?appid=' . $appid . '&secret=' . $secret . '&js_code=' . $js_code . '&grant_type=authorization_code', 'get');
return json_decode($logsList);
}
/**
*
* @param string $appid
* @param string $secret
* @param string $js_code
* @return array 包含以下键的关联数组:
* - errmsg: string 错误信息
* - errcode: int 错误码
* - session_key: string 会话密钥
* - openid: string 用户OpenID
* - unionid: string 用户UnionID(如果有)
* @throws Exception 如果获取令牌失败,则抛出异常
*/
public function dY_Info($appid, $secret, $js_code)
{
$logsList = httpRequest('https://minigame.zijieapi.com/mgplatform/api/apps/jscode2session?appid=' . $appid . '&secret=' . $secret . '&code=' . $js_code, 'get');
return json_decode($logsList);
}
// 将表情进行转义 用于存储的时候
function emoji_encode($str)
{
$strEncode = '';
$length = mb_strlen($str, 'utf-8');
for ($i = 0; $i = 4) {
$strEncode .= '[[EMOJI:' . rawurlencode($_tmpStr) . ']]';
} else {
$strEncode .= $_tmpStr;
}
}
return $strEncode;
}
/**
* 用户反馈
*
* @return array
*/
public function feedback($userInfo)
{
$content = Request::param('content'); // 0 测试环境 1 微信小程序 2抖音小程序
$title = Request::param('title'); // 0 测试环境 1 微信小程序 2抖音小程序
$thumb = Request::param('thumb'); // 0 测试环境 1 微信小程序 2抖音小程序
Db::startTrans();
try {
$mess = new Message();
if (! isset($title)) {
$title = "";
}
if (! isset($thumb)) {
$title = "";
}
$res = $mess->addMessageData($userInfo['user_id'], $title, 0, $content, $thumb = '', 1);
// $where_time = strtotime(date('Y-m-d').'00:00:00');
// $userFo = UsersMessage::where('user_id',$userInfo['user_id'])->setInc('game_level',1);
Db::commit();
return [
'code' => ReturnCode::SUCCESS_CODE,
'操作成功',
'data' => $res
];
} catch (\Exception $e) {
Db::rollback();
Log::write('操作失败: ' . $e->getMessage(), 'error');
return [
'code' => ReturnCode::ERROR_CODE,
'msg' => $e->getMessage()
];
}
}
/**
* 分享
* @param string $url 分享出去后跳转的链接
* @return array mixed
*/
public function getApiTicketAction($url)
{
$appid = zf_cache("web_info.appid");
$secret = zf_cache("web_info.appsecret");
$jsapiTicket = $this->getJsapiTicket();
$timestamp = time();
$nonceStr = $this->createNonceStr(); // 构造一个随机数,用来生成签名的一部分
$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; // 签名算法先按照ascII码排序
$signature = sha1($string); // 对排序好的字符串加密
return array(
'appId' => $appid,
'nonceStr' => $nonceStr,
'timestamp' => $timestamp,
'signature' => $signature
);
}
// 构造一个随机数,用来生成签名的一部分
public function createNonceStr($length = 16)
{ // 生成随机16个字符的字符串
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$str = "";
for ($i = 0; $i find();
if ($access_token_list['ticket_expires_time'] > time()) {
$ticket = $access_token_list['ticket'];
return $ticket;
} else {
if ($access_token_list['expires_time'] > time()) {
$token = $access_token_list['access_token'];
} else {
$res = file_get_contents('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $secret);
$res = json_decode($res, true);
if (isset($res['errcode']) && ! empty($res['errcode'])) {
throw new \Exception($res['errmsg']);
}
$token = $res['access_token'];
}
$res2 = file_get_contents("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $token . "&type=jsapi");
$res2 = json_decode($res, true);
if (isset($res2['errcode']) && ! empty($res2['errcode'])) {
throw new \Exception($res2['errmsg']);
}
$ticket = $res2['ticket'];
// ticket 不能频繁的访问接口来获取,在每次获取后,我们把它保存到数据库中。
if ($ticket) {
$data = array(
'access_token' => $token,
'expires_time' => $time,
'expires_in' => '7000',
'ticket' => $ticket,
'ticket_expires_time' => $time
);
AccessToken::where('id', 1)->update($data); // 把获得的token存储到数据库中
}
return $ticket;
}
}
}