发票管理apiadmin
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

256 lines
7.7 KiB

<?php
declare (strict_types = 1);
namespace app\service\user;
use app\model\WechatUser;
use app\service\BaseService;
use fast\Http;
use think\facade\Cookie;
use think\facade\Session;
class LoginService extends BaseService
{
/**
* 判断登录状态
* @return bool
*/
public function isLogin()
{
if (!$this->user) {
return false;
}
return true;
}
/**
* 登录凭证校验
* @param $code
* @param $iv
* @param $encryptedData
* @return array
* @throws \fast\FuncException
*/
public function code2session($code, $iv, $encryptedData)
{
$http = new Http();
$url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . env("app.appid") . "&secret=" . env("app.appsecret") . "&js_code={$code}&grant_type=authorization_code";
$res = $http::get($url);
if ($res['code'] != 200) {
throw new \fast\FuncException($res['msg']);
}
$res['data'] = json_decode($res['data'], true);
if (isset($res['data']['errcode'])) {
throw new \fast\FuncException($res['data']['errmsg']);
}
session('app_openid', $res['data']['openid']);
session('app_session_key', $res['data']['session_key']);
$res['userInfo'] = json_decode($this->decodeWechatIv($iv, $encryptedData), true);
$result = [];
$result['openid'] = $res['data']['openid'];
if (isset($res['data']['unionid'])) $result['unionid'] = $res['data']['unionid'];
$result['phone'] = $res['userInfo']['phoneNumber'];
return $result;
}
/**
* 解密微信的iv和encryptedData
* @param $iv
* @param $encryptedData
* @return false|string
* @throws \fast\FuncException
*/
public function decodeWechatIv($iv, $encryptedData)
{
$openid = session('app_openid');
$session_key = session('app_session_key');
if (!$openid || !$session_key) {
throw new \fast\FuncException('缺少主要参数');
}
if (strlen($session_key) != 24) {
throw new \fast\FuncException('sessionkey长度错误');
}
if (strlen($iv) != 24) {
throw new \fast\FuncException('iv长度错误');
}
$aesKey = base64_decode($session_key);
$aesIV = base64_decode($iv);
$aesCipher = base64_decode($encryptedData);
$result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
$dataObj = json_decode($result);
if ($dataObj == NULL) {
throw new \fast\FuncException('登录失败,请稍候再试');
}
if ($dataObj->watermark->appid != env("app.appid")) {
throw new \fast\FuncException('小程序appid不一致,登录失败');
}
return $result;
}
/**
* 用户端登录
* @param $phone
* @param $openid
* @param $unionid
* @return WechatUser|mixed
* @throws \fast\FuncException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function userLogin($phone, $openid, $unionid)
{
$field = 'id,openid,phone,nickname,sex,headimgurl';
$user = WechatUser::where('phone', $phone)->where('delete_time', 0)->field($field)->find();
if ($openid != $user->openid) {
WechatUser::where('id', $user->id)->save(['openid' => $user->openid]);
}
if ($user) {
return $this->userSuccess($user);
}
return $this->register($phone, $openid, $unionid);
}
/**
*
* @param $phone
* @return WechatUser|array|mixed
* @throws \fast\FuncException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function userPhoneLogin($phone)
{
$field = 'id,openid,phone,nickname,sex,headimgurl';
$user = WechatUser::where('phone', $phone)->where('delete_time', 0)->field($field)->find();
if ($user) {
return $this->userSuccess($user);
}
return $this->register($phone);
}
/**
* 用户登录成功
* @param WechatUser $user
* @return array
*/
public function userSuccess(WechatUser $user)
{
session('user', $user->toArray());
$this->userKeeplogin($user->id,$user->openid,3600 * 24 * 7);
// $user->visible(['id', 'name', 'logo']);
return $user->toArray();
}
/**
* 保持登录
* @param $user_id
* @param $token
* @param $keeptime
* @return bool
*/
protected function userKeeplogin($user_id, $token, $keeptime = 0)
{
if ($keeptime) {
$expiretime = time() + $keeptime;
$key = md5(md5(strval($user_id)) . md5(strval($keeptime)) . md5(strval($expiretime)) . $token);
error_reporting(E_ALL);
ini_set('display_errors', '1');
$data = [$user_id, $keeptime, $expiretime, $key];
Cookie::set('userKeeplogin', implode('|', $data), 86400 * 30);
return true;
}
return false;
}
/**
* 用户端注册
* @param $phone
* @param string $openid
* @param string $unionid
* @return WechatUser|mixed
* @throws \fast\FuncException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function register($phone, string $openid = '', string $unionid = '')
{
$add = [
'phone' => $phone,
'openid' => $openid,
'nickname' => '微信用户',
'unionid' => $unionid ?? '',
];
$id = (new WechatUser())->insertGetId($add);
if (!$id) {
throw new \fast\FuncException('注册失败,请稍候再试');
}
$user = WechatUser::where('id', $id)->find();
return $this->userSuccess($user);
}
/**
* 自动登录
* @return WechatUser|array|false|mixed|\think\Model
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function userAutologin() {
$keeplogin = Cookie::get('userKeeplogin');
if (!$keeplogin) {
return false;
}
[$id, $keeptime, $expiretime, $key] = explode('|', $keeplogin);
if ($id && $keeptime && $expiretime && $key && $expiretime > time()) {
$user = WechatUser::where('id', $id)->find();
if (!$user || !$user->token) {
return false;
}
unset($user->password);
//token有变更
if ($key != md5(md5($id) . md5($keeptime) . md5($expiretime) . $user->token)) {
return false;
}
Session::set('user', $user->toArray());
//刷新自动登录的时效
$this->userKeeplogin($id,$user->token,$keeptime);
return $user;
} else {
return false;
}
}
/**
* 登出
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function userLogout() {
$user = WechatUser::find($this->user_id);
if ($user) {
$user->token = '';
$user->save();
}
Session::delete('user');
Cookie::delete('userKeeplogin');
return true;
}
}