cxfoot/modules/api/models/LoginByWxoaForm.php
2023-10-27 16:06:22 +08:00

215 lines
6.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @author Any
* @description KISS
* @date 2020-12-3
* @version 1.0.0
*
* _____LOG_____
*
*/
namespace app\modules\api\models;
use app\models\User;
use app\components\auth\AToken;
use app\components\wechat\aes\WxBizDataCrypt;
use app\models\UserOauth;
use app\models\common\CommonUserEditForm;
use app\components\SysConst;
use app\components\FlashStorage;
class LoginByWxoaForm extends ApiModel
{
public $code;
public $code_expires;//code是否过期0=否1=是
public $cx_mch_id;
public $token_type;
public $wechat_mp;
public function rules()
{
return [
[['code'], 'trim'],
[['code'], 'string'],
[['code_expires'], 'integer'],
[['code', 'token_type', 'wechat_mp'], 'required'],
];
}
public function login()
{
if (!$this->validate()) {
return $this->getModelError();
}
$res = FlashStorage::getCache("m{$this->cx_mch_id}_c{$this->code}");
if ($this->code_expires == 1 || $res === false) {
$res = $this->code2session($this->code);
if ($res['code'] != 0)
return $res;
FlashStorage::setCache("m{$this->cx_mch_id}_c{$this->code}", $res, 864000);
}
$session_key = $res['data']['session_key'];
$openid = $res['data']['openid'];
$unionid = isset($res['data']['unionid']) ? $res['data']['unionid'] : null;
$res = $this->decrypted_data($session_key);
if ($res['code'] != 0) {
return $res;
}
$decrypted_info = json_decode($res['data'], true);
$openid = $openid ? $openid : $decrypted_info['openId'];
$nickname = $decrypted_info['nickName'];
$avatar_url = empty($decrypted_info['avatarUrl']) ? User::DEFAULT_AVATAR_URL : $decrypted_info['avatarUrl'];
$gender = $decrypted_info['gender'];
if ($unionid == null) {
$unionid = isset($decrypted_info['unionId']) ? $decrypted_info['unionId'] : '0';
}
//用户是否存在
$user_oauth = null;
if ($unionid != 0) {
//优选使用unionid
$user_oauth = UserOauth::findOne([
'cx_mch_id' => $this->cx_mch_id,
'is_delete' => 0,
'unionid' => $unionid
]);
}
if ($user_oauth == null) {
$user_oauth = UserOauth::findOne([
'cx_mch_id' => $this->cx_mch_id,
'is_delete' => 0,
'type' => SysConst::$cxOauthProviderWxmp,
'openid' => $openid
]);
}
$t = \Yii::$app->db->beginTransaction();
if ($user_oauth != null) {
//用户是否存在
$user = User::findOne([
'id' => $user_oauth->user_id,
'is_delete' => 0,
'cx_mch_id' => $this->cx_mch_id,
'status' => User::STATUS_NORMAL
]);
if ($user == null) {
\Yii::error("[LoginByWxmpForm] 用户(ID:{$user_oauth->user_id})不存在");
return [
'code' => 1,
'msg' => '系统内部异常,请联系管理员'
];
}
} else {
$form = new CommonUserEditForm();
$form->scenario = 'wxmp_signup';
$form->model = new User();
$form->cx_mch_id = $this->cx_mch_id;
$form->username = User::generateUsername(3, "wx", 6);
$form->nickname = $nickname;
$form->avatar_url = $avatar_url;
$form->access_token = \Yii::$app->security->generateRandomString();
$form->gender = $gender;
$form->is_modify_un = 1;
$res = $form->save();
if ($res['code'] != 0)
return $res;
$user = $form->model;
$user_oauth = new UserOauth();
$user_oauth->cx_mch_id = $this->cx_mch_id;
$user_oauth->type = SysConst::$cxOauthProviderWxmp;
$user_oauth->user_id = $user->id;
$user_oauth->openid = $openid;
$user_oauth->unionid = $unionid;
$user_oauth->is_delete = 0;
$user_oauth->created_at = time();
}
//更新用户信息
$user_oauth->nickname = $nickname;
$user_oauth->avatar_url = $avatar_url;
if ($unionid !== 0 && $user_oauth->unionid == 0) {
$user_oauth->unionid = $unionid;
}
if (!$user_oauth->save()) {
$t->rollBack();
return $this->getModelError($user_oauth);
}
if (!\Yii::$app->user->login($user)) {
$t->commit();
return [
'code' => 1,
'msg' => '登录失败'
];
}
$args = [];
$args['cx_mch_id'] = $this->cx_mch_id;
$args['token_type'] = $this->token_type;
$atoken = new AToken($args);
$data = $atoken->generate_access_token();
if ($data['code'] == 0) {
$err_msg = "微信小程序登录成功";
User::lastLogin($user->id, 1, $err_msg, $this->cx_mch_id);
}
$t->commit();
//是否需要绑定
$data = User::bindQuery($user_oauth->user, $data);
return $data;
}
/***
* 用户数据解密
*/
private function decrypted_data($session_key)
{
$pc = new WxBizDataCrypt($this->wechat_mp->appId, $session_key);
$errCode = $pc->decryptData($this->encrypted_data, $this->iv, $data);
if ($errCode == 0) {
return [
'code' => 0,
'msg' => 'success',
'data' => $data
];
} else {
return [
'code' => 1,
'msg' => $errCode,
];
}
}
private function code2session($code)
{
$api = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->wechat_mp->appId}&secret={$this->wechat_mp->appSecret}&code=" . $code . "&grant_type=authorization_code";
$this->wechat_mp->curl->get($api);
if ($this->wechat_mp->curl->error_code != 0) {
return [
'code' => 1,
'msg' => "err_code:{$this->wechat_mp->curl->error_code}err_msg:{$this->wechat_mp->curl->error_msg}"
];
}
$resp = $this->wechat_mp->curl->response;
$res = json_decode($resp, true);
if (!isset($res['access_token']) || !isset($res['openid'])) {
return [
'code' => 1,
'msg' => isset($res['errmsg']) ? $res['errmsg'] : 'error'
];
}
return [
'code' => 0,
'msg' => 'ok',
'data' => $res
];
}
}