323 lines
9.5 KiB
PHP
323 lines
9.5 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
||
// +----------------------------------------------------------------------
|
||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||
// | 开源版本可自由商用,可去除界面版权logo
|
||
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
|
||
// | github下载:https://github.com/likeshop-github/likeadmin
|
||
// | 访问官网:https://www.likeadmin.cn
|
||
// | likeadmin团队 版权所有 拥有最终解释权
|
||
// +----------------------------------------------------------------------
|
||
// | author: likeadminTeam
|
||
// +----------------------------------------------------------------------
|
||
|
||
namespace app\teamapi\logic;
|
||
|
||
use app\common\cache\WebScanLoginCache;
|
||
use app\common\logic\BaseLogic;
|
||
use app\common\model\store\StoreUser;
|
||
use app\teamapi\service\{TeamUserTokenService, WechatUserService};
|
||
use app\common\enum\{LoginEnum, notice\NoticeEnum, user\UserTerminalEnum, YesNoEnum};
|
||
use app\common\service\{ConfigService,
|
||
FileService,
|
||
sms\SmsDriver,
|
||
wechat\WeChatConfigService,
|
||
wechat\WeChatMnpService,
|
||
wechat\WeChatOaService,
|
||
wechat\WeChatRequestService};
|
||
//use app\common\model\teamster\{TeamasterUser, UserAuth};
|
||
use app\common\model\teamaster\TeamasterUser;
|
||
use think\facade\{Db, Config};
|
||
|
||
/**
|
||
* 登录逻辑
|
||
* Class LoginLogic
|
||
* @package app\api\logic
|
||
*/
|
||
class TeamLoginLogic extends BaseLogic
|
||
{
|
||
|
||
|
||
/**
|
||
* @notes 账号/手机号登录,手机号验证码
|
||
* @param $params
|
||
* @return array|false
|
||
* @author 段誉
|
||
* @date 2022/9/6 19:26
|
||
*/
|
||
public static function login($params)
|
||
{
|
||
Db::startTrans();
|
||
try {
|
||
// 账号/手机号 密码登录
|
||
$where = ['account|mobile' => $params['account']];
|
||
if ($params['scene'] == LoginEnum::MOBILE_CAPTCHA) {
|
||
//手机验证码登录
|
||
$where = ['mobile' => $params['mobile']];
|
||
}else{
|
||
$passwordSalt = Config::get('project.unique_identification');
|
||
$password = create_password($params['password'], $passwordSalt);
|
||
$where = ['mobile' => $params['account'],'password'=>$password];
|
||
}
|
||
$user = TeamasterUser::where($where)->findOrEmpty();
|
||
|
||
|
||
if ($user->isEmpty()) {
|
||
throw new \Exception('账号密码不正确');
|
||
}
|
||
|
||
//更新登录信息
|
||
$user->login_time = time();
|
||
$user->login_ip = request()->ip();
|
||
$user->save();
|
||
|
||
//设置token
|
||
$userInfo = TeamUserTokenService::setToken($user->id, $params['terminal']);
|
||
|
||
//返回登录信息
|
||
$avatar = $user->avatar ?: Config::get('project.default_image.user_avatar');
|
||
$avatar = FileService::getImgUrl($avatar);
|
||
Db::commit();
|
||
return [
|
||
'nickname' => $userInfo['nickname'],
|
||
'sn' => $userInfo['sn'],
|
||
'mobile' => $userInfo['mobile'],
|
||
'avatar' => $avatar,
|
||
'token' => $userInfo['token'],
|
||
];
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
self::setError($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 退出登录
|
||
* @param $userInfo
|
||
* @return bool
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
* @author 段誉
|
||
* @date 2022/9/16 17:56
|
||
*/
|
||
public static function logout($userInfo)
|
||
{
|
||
//token不存在,不注销
|
||
if (!isset($userInfo['token'])) {
|
||
return false;
|
||
}
|
||
|
||
//设置token过期
|
||
return TeamUserTokenService::expireToken($userInfo['token']);
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 获取微信请求code的链接
|
||
* @param string $url
|
||
* @return string
|
||
* @author 段誉
|
||
* @date 2022/9/20 19:47
|
||
*/
|
||
public static function codeUrl(string $url)
|
||
{
|
||
return (new WeChatOaService())->getCodeUrl($url);
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @notes 更新登录信息
|
||
* @param $userId
|
||
* @throws \Exception
|
||
* @author 段誉
|
||
* @date 2022/9/20 19:46
|
||
*/
|
||
public static function updateLoginInfo($userId)
|
||
{
|
||
$user = User::findOrEmpty($userId);
|
||
if ($user->isEmpty()) {
|
||
throw new \Exception('用户不存在');
|
||
}
|
||
|
||
$time = time();
|
||
$user->login_time = $time;
|
||
$user->login_ip = request()->ip();
|
||
$user->update_time = $time;
|
||
$user->save();
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 小程序端绑定微信
|
||
* @param array $params
|
||
* @return bool
|
||
* @author 段誉
|
||
* @date 2022/9/20 19:46
|
||
*/
|
||
public static function mnpAuthLogin(array $params)
|
||
{
|
||
try {
|
||
//通过code获取微信openid
|
||
$response = (new WeChatMnpService())->getMnpResByCode($params['code']);
|
||
$response['user_id'] = $params['user_id'];
|
||
$response['terminal'] = UserTerminalEnum::WECHAT_MMP;
|
||
|
||
return self::createAuth($response);
|
||
|
||
} catch (\Exception $e) {
|
||
self::$error = $e->getMessage();
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 公众号端绑定微信
|
||
* @param array $params
|
||
* @return bool
|
||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||
* @author 段誉
|
||
* @date 2022/9/16 10:43
|
||
*/
|
||
public static function oaAuthLogin(array $params)
|
||
{
|
||
try {
|
||
//通过code获取微信openid
|
||
$response = (new WeChatOaService())->getOaResByCode($params['code']);
|
||
$response['user_id'] = $params['user_id'];
|
||
$response['terminal'] = UserTerminalEnum::WECHAT_OA;
|
||
|
||
return self::createAuth($response);
|
||
|
||
} catch (\Exception $e) {
|
||
self::$error = $e->getMessage();
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 生成授权记录
|
||
* @param $response
|
||
* @return bool
|
||
* @throws \Exception
|
||
* @author 段誉
|
||
* @date 2022/9/16 10:43
|
||
*/
|
||
public static function createAuth($response)
|
||
{
|
||
//先检查openid是否有记录
|
||
$isAuth = UserAuth::where('openid', '=', $response['openid'])->findOrEmpty();
|
||
if (!$isAuth->isEmpty()) {
|
||
throw new \Exception('该微信已被绑定');
|
||
}
|
||
|
||
if (isset($response['unionid']) && !empty($response['unionid'])) {
|
||
//在用unionid找记录,防止生成两个账号,同个unionid的问题
|
||
$userAuth = UserAuth::where(['unionid' => $response['unionid']])
|
||
->findOrEmpty();
|
||
if (!$userAuth->isEmpty() && $userAuth->user_id != $response['user_id']) {
|
||
throw new \Exception('该微信已被绑定');
|
||
}
|
||
}
|
||
|
||
//如果没有授权,直接生成一条微信授权记录
|
||
UserAuth::create([
|
||
'user_id' => $response['user_id'],
|
||
'openid' => $response['openid'],
|
||
'unionid' => $response['unionid'] ?? '',
|
||
'terminal' => $response['terminal'],
|
||
]);
|
||
return true;
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 获取扫码登录地址
|
||
* @return array|false
|
||
* @author 段誉
|
||
* @date 2022/10/20 18:23
|
||
*/
|
||
public static function getScanCode($redirectUri)
|
||
{
|
||
try {
|
||
$config = WeChatConfigService::getOpConfig();
|
||
$appId = $config['app_id'];
|
||
$redirectUri = UrlEncode($redirectUri);
|
||
|
||
// 设置有效时间标记状态, 超时扫码不可登录
|
||
$state = MD5(time().rand(10000, 99999));
|
||
(new WebScanLoginCache())->setScanLoginState($state);
|
||
|
||
// 扫码地址
|
||
$url = WeChatRequestService::getScanCodeUrl($appId, $redirectUri, $state);
|
||
return ['url' => $url];
|
||
|
||
} catch (\Exception $e) {
|
||
self::$error = $e->getMessage();
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 更新用户信息
|
||
* @param $params
|
||
* @param $userId
|
||
* @return User
|
||
* @author 段誉
|
||
* @date 2023/2/22 11:19
|
||
*/
|
||
public static function updateUser($params, $userId)
|
||
{
|
||
return TeamasterUser::where(['id' => $userId])->update([
|
||
'nickname' => $params['nickname'],
|
||
'avatar' => FileService::setFileUrl($params['avatar']),
|
||
'is_new_user' => YesNoEnum::NO
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* @notes 重置登录密码
|
||
* @param $params
|
||
* @return bool
|
||
* @author 段誉
|
||
* @date 2022/9/16 18:06
|
||
*/
|
||
public static function resetPassword(array $params)
|
||
{
|
||
// Db::startTrans();
|
||
try {
|
||
// 校验验证码
|
||
$smsDriver = new SmsDriver();
|
||
if (!$smsDriver->verify($params['mobile'], $params['code'], NoticeEnum::FIND_MOBILE_CAPTCHA)) {
|
||
throw new \Exception('验证码错误');
|
||
}
|
||
|
||
// 重置密码
|
||
$passwordSalt = Config::get('project.unique_identification');
|
||
$password = create_password($params['password'], $passwordSalt);
|
||
if($params['password']!= $params['password_confirm']){
|
||
throw new \Exception('两次输入不正确');
|
||
}
|
||
// 更新
|
||
TeamasterUser::where('mobile', $params['mobile'])->update([
|
||
'password' => $password
|
||
]);
|
||
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
self::setError($e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
} |