| 
									
										
										
										
											2023-08-10 14:59:52 +08:00
										 |  |  |  | <?php | 
					
						
							|  |  |  |  | // +----------------------------------------------------------------------
 | 
					
						
							|  |  |  |  | // | likeshop开源商城系统
 | 
					
						
							|  |  |  |  | // +----------------------------------------------------------------------
 | 
					
						
							|  |  |  |  | // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
 | 
					
						
							|  |  |  |  | // | gitee下载:https://gitee.com/likeshop_gitee
 | 
					
						
							|  |  |  |  | // | github下载:https://github.com/likeshop-github
 | 
					
						
							|  |  |  |  | // | 访问官网:https://www.likeshop.cn
 | 
					
						
							|  |  |  |  | // | 访问社区:https://home.likeshop.cn
 | 
					
						
							|  |  |  |  | // | 访问手册:http://doc.likeshop.cn
 | 
					
						
							|  |  |  |  | // | 微信公众号:likeshop技术社区
 | 
					
						
							|  |  |  |  | // | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
 | 
					
						
							|  |  |  |  | // |  likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
 | 
					
						
							|  |  |  |  | // | 禁止对系统程序代码以任何目的,任何形式的再发布
 | 
					
						
							|  |  |  |  | // | likeshop团队版权所有并拥有最终解释权
 | 
					
						
							|  |  |  |  | // +----------------------------------------------------------------------
 | 
					
						
							|  |  |  |  | // | author: likeshop.cn.team
 | 
					
						
							|  |  |  |  | // +----------------------------------------------------------------------
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | namespace app\api\logic; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | use app\admin\logic\user\LevelLogic; | 
					
						
							|  |  |  |  | use app\api\server\UserServer; | 
					
						
							|  |  |  |  | use app\common\basics\Logic; | 
					
						
							|  |  |  |  | use app\common\enum\ClientEnum; | 
					
						
							|  |  |  |  | use app\common\model\distribution\Distribution; | 
					
						
							| 
									
										
										
										
											2023-09-26 09:59:15 +08:00
										 |  |  |  | use app\common\model\user\UserApi; | 
					
						
							| 
									
										
										
										
											2023-08-10 14:59:52 +08:00
										 |  |  |  | use app\common\server\WeChatServer; | 
					
						
							|  |  |  |  | use app\common\server\ConfigServer; | 
					
						
							|  |  |  |  | use app\common\model\Client_; | 
					
						
							|  |  |  |  | use app\common\model\user\User; | 
					
						
							|  |  |  |  | use app\common\model\user\UserAuth; | 
					
						
							|  |  |  |  | use app\common\model\user\UserLevel; | 
					
						
							|  |  |  |  | use app\common\model\Session as SessionModel; | 
					
						
							|  |  |  |  | use EasyWeChat\Factory; | 
					
						
							|  |  |  |  | use think\facade\Config; | 
					
						
							|  |  |  |  | use think\facade\Cache; | 
					
						
							|  |  |  |  | use think\facade\Db; | 
					
						
							|  |  |  |  | use app\api\cache\TokenCache; | 
					
						
							|  |  |  |  | use app\common\logic\AccountLogLogic; | 
					
						
							|  |  |  |  | use app\common\model\AccountLog; | 
					
						
							|  |  |  |  | use app\common\server\UrlServer; | 
					
						
							|  |  |  |  | use think\Exception; | 
					
						
							|  |  |  |  | use Requests; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class LoginLogic extends Logic | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * Notes: 旧用户登录 | 
					
						
							|  |  |  |  |      * @param $post | 
					
						
							|  |  |  |  |      * @author 段誉(2021/4/19 16:57) | 
					
						
							|  |  |  |  |      * @return array | 
					
						
							|  |  |  |  |      * @throws \think\Exception | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\DataNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\ModelNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\exception\DbException | 
					
						
							|  |  |  |  |      * @throws \think\exception\PDOException | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function silentLogin($post) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try { | 
					
						
							|  |  |  |  |             //通过code获取微信 openid
 | 
					
						
							|  |  |  |  |             $response = self::getWechatResByCode($post); | 
					
						
							|  |  |  |  |             //通过获取到的openID或unionid获取当前 系统 用户id
 | 
					
						
							|  |  |  |  |             $user_id = self::getUserByWechatResponse($response); | 
					
						
							|  |  |  |  |         } catch (\Exception $e) { | 
					
						
							|  |  |  |  |             self::$error = $e->getMessage(); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-21 17:14:07 +08:00
										 |  |  |  |         // 将openid返回给前端缓存 支付的时候降openid传给后端
 | 
					
						
							| 
									
										
										
										
											2023-08-10 14:59:52 +08:00
										 |  |  |  |         if (empty($user_id)) { | 
					
						
							|  |  |  |  |             //系统中没有用户-调用authlogin接口生成新用户
 | 
					
						
							| 
									
										
										
										
											2023-08-21 17:14:07 +08:00
										 |  |  |  |             return ['openid' => $response['openid'] ?? '']; | 
					
						
							| 
									
										
										
										
											2023-08-10 14:59:52 +08:00
										 |  |  |  |         } else { | 
					
						
							|  |  |  |  |             $user_info = UserServer::updateUser($response, Client_::mnp, $user_id); | 
					
						
							| 
									
										
										
										
											2023-08-21 17:14:07 +08:00
										 |  |  |  |             $user_info['openid'] = $response['openid'] ?? ''; | 
					
						
							| 
									
										
										
										
											2023-08-10 14:59:52 +08:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         //验证用户信息
 | 
					
						
							|  |  |  |  |         $check_res = self::checkUserInfo($user_info); | 
					
						
							|  |  |  |  |         if (true !== $check_res) { | 
					
						
							|  |  |  |  |             self::$error = $check_res; | 
					
						
							|  |  |  |  |             return  false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         //创建会话
 | 
					
						
							|  |  |  |  |         $user_info['token'] = self::createSession($user_info['id'], Client_::mnp); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         unset($user_info['id'], $user_info['disable']); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return $user_info->toArray(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * Notes: 新用户登录 | 
					
						
							|  |  |  |  |      * @param $post | 
					
						
							|  |  |  |  |      * @author 段誉(2021/4/19 16:57) | 
					
						
							|  |  |  |  |      * @return array | 
					
						
							|  |  |  |  |      * @throws \think\Exception | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\DataNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\ModelNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\exception\DbException | 
					
						
							|  |  |  |  |      * @throws \think\exception\PDOException | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function authLogin($post) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try { | 
					
						
							|  |  |  |  |             //通过code获取微信 openid
 | 
					
						
							|  |  |  |  |             $response = self::getWechatResByCode($post); | 
					
						
							|  |  |  |  |             $response['headimgurl'] = $post['headimgurl'] ?? ''; | 
					
						
							|  |  |  |  |             $response['nickname'] = $post['nickname'] ?? ''; | 
					
						
							|  |  |  |  |             //通过获取到的openID或unionid获取当前 系统 用户id
 | 
					
						
							|  |  |  |  |             $user_id = self::getUserByWechatResponse($response); | 
					
						
							|  |  |  |  |         } catch (\Exception $e) { | 
					
						
							|  |  |  |  |             self::$error = $e->getMessage(); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (empty($user_id)) { | 
					
						
							|  |  |  |  |             $user_info = UserServer::createUser($response, Client_::mnp); | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             $user_info = UserServer::updateUser($response, Client_::mnp, $user_id); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         //验证用户信息
 | 
					
						
							|  |  |  |  |         $check_res = self::checkUserInfo($user_info); | 
					
						
							|  |  |  |  |         if (true !== $check_res) { | 
					
						
							|  |  |  |  |             self::$error = $check_res; | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         //创建会话
 | 
					
						
							|  |  |  |  |         $user_info['token'] = self::createSession($user_info['id'], Client_::mnp); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         unset($user_info['id'], $user_info['disable']); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return $user_info->toArray(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * Notes: 根据code 获取微信信息(openid, unionid) | 
					
						
							|  |  |  |  |      * @param $post | 
					
						
							|  |  |  |  |      * @author 段誉(2021/4/19 16:52) | 
					
						
							|  |  |  |  |      * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string | 
					
						
							|  |  |  |  |      * @throws Exception | 
					
						
							|  |  |  |  |      * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function getWechatResByCode($post) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         $config = WeChatServer::getMnpConfig(); | 
					
						
							|  |  |  |  |         $app = Factory::miniProgram($config); | 
					
						
							|  |  |  |  |         $response = $app->auth->session($post['code']); | 
					
						
							|  |  |  |  |         if (!isset($response['openid']) || empty($response['openid'])) { | 
					
						
							|  |  |  |  |             throw new \think\Exception('获取openID失败'); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return $response; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * Notes: 根据微信返回信息查询当前用户id | 
					
						
							|  |  |  |  |      * @param $response | 
					
						
							|  |  |  |  |      * @author 段誉(2021/4/19 16:52) | 
					
						
							|  |  |  |  |      * @return mixed | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function getUserByWechatResponse($response) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         $user_id = UserAuth::alias('au') | 
					
						
							|  |  |  |  |             ->join('user u', 'au.user_id=u.id') | 
					
						
							|  |  |  |  |             ->where(['u.del' => 0]) | 
					
						
							|  |  |  |  |             ->where(function ($query) use ($response) { | 
					
						
							|  |  |  |  |                 $query->whereOr(['au.openid' => $response['openid']]); | 
					
						
							|  |  |  |  |                 if(isset($response['unionid']) && !empty($response['unionid'])){ | 
					
						
							|  |  |  |  |                     $query->whereOr(['au.unionid' => $response['unionid']]); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             }) | 
					
						
							|  |  |  |  |             ->value('user_id'); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return $user_id; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * Notes: 检查用户信息 | 
					
						
							|  |  |  |  |      * @param $user_info | 
					
						
							|  |  |  |  |      * @author 段誉(2021/4/19 16:54) | 
					
						
							|  |  |  |  |      * @return bool|string | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function checkUserInfo($user_info) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (empty($user_info)) { | 
					
						
							|  |  |  |  |             return '登录失败:user'; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if ($user_info['disable']) { | 
					
						
							|  |  |  |  |             return '该用户被禁用'; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return true; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * 创建会话 | 
					
						
							|  |  |  |  |      * @param $user_id | 
					
						
							|  |  |  |  |      * @param $client | 
					
						
							|  |  |  |  |      * @return string | 
					
						
							|  |  |  |  |      * @throws \think\Exception | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\DataNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\ModelNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\exception\DbException | 
					
						
							|  |  |  |  |      * @throws \think\exception\PDOException | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function createSession($user_id, $client) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         //清除之前缓存
 | 
					
						
							|  |  |  |  |         $token = SessionModel::where(['user_id' => $user_id, 'client' => $client]) | 
					
						
							|  |  |  |  |             ->value('token'); | 
					
						
							|  |  |  |  |         if($token) { | 
					
						
							|  |  |  |  |             Cache::delete($token); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         $result = SessionModel::where(['user_id' => $user_id, 'client' => $client]) | 
					
						
							|  |  |  |  |             ->findOrEmpty(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         $time = time(); | 
					
						
							|  |  |  |  |         $expire_time = $time + Config::get('project.token_expire_time'); | 
					
						
							|  |  |  |  |         // 新token
 | 
					
						
							|  |  |  |  |         $token = md5($user_id . $client . $time); | 
					
						
							|  |  |  |  |         $data = [ | 
					
						
							|  |  |  |  |             'user_id' => $user_id, | 
					
						
							|  |  |  |  |             'token' => $token, | 
					
						
							|  |  |  |  |             'client' => $client, | 
					
						
							|  |  |  |  |             'update_time' => $time, | 
					
						
							|  |  |  |  |             'expire_time' => $expire_time, | 
					
						
							|  |  |  |  |         ]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if ($result->isEmpty()) { | 
					
						
							|  |  |  |  |             SessionModel::create($data); | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             SessionModel::where(['user_id' => $user_id, 'client' => $client]) | 
					
						
							|  |  |  |  |                 ->update($data); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         //更新登录信息
 | 
					
						
							|  |  |  |  |         $login_ip = $ip = request()->ip(); | 
					
						
							|  |  |  |  |         User::where(['id' => $user_id]) | 
					
						
							|  |  |  |  |             ->update(['login_time' => $time, 'login_ip' => $login_ip]); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 获取最新的用户信息
 | 
					
						
							|  |  |  |  |         $user_info = User::alias('u') | 
					
						
							|  |  |  |  |             ->join('session s', 'u.id=s.user_id') | 
					
						
							|  |  |  |  |             ->where(['s.token' => $token]) | 
					
						
							|  |  |  |  |             ->field('u.*,s.token,s.client') | 
					
						
							|  |  |  |  |             ->find(); | 
					
						
							|  |  |  |  |         $user_info = $user_info ? $user_info->toArray() : []; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         //创建新的缓存
 | 
					
						
							|  |  |  |  |         $ttl = 0 + Config::get('project.token_expire_time'); | 
					
						
							|  |  |  |  |         Cache::set($token, $user_info, $ttl); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return $token; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     public static function register($post) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         Db::startTrans(); | 
					
						
							|  |  |  |  |         try{ | 
					
						
							|  |  |  |  |             $time = time(); | 
					
						
							|  |  |  |  |             $salt = substr(md5($time . $post['mobile']), 0, 4);//随机4位密码盐
 | 
					
						
							|  |  |  |  |             $password = create_password($post['password'], $salt);//生成密码
 | 
					
						
							|  |  |  |  |             $user_data = [ | 
					
						
							|  |  |  |  |                 'avatar'        => ConfigServer::get('website', 'user_image'), | 
					
						
							|  |  |  |  |                 'sn'            => create_user_sn(), | 
					
						
							|  |  |  |  |                 'mobile'        => $post['mobile'], | 
					
						
							|  |  |  |  |                 'salt'          => $salt, | 
					
						
							|  |  |  |  |                 'password'      => $password, | 
					
						
							|  |  |  |  |                 'create_time'   => $time, | 
					
						
							|  |  |  |  |                 'distribution_code' => generate_invite_code(),//分销邀请码
 | 
					
						
							|  |  |  |  |                 'is_distribution' => DistributionLogic::isDistributionMember(),//是否为分销会员
 | 
					
						
							|  |  |  |  |                 'client' => $post['client'] | 
					
						
							|  |  |  |  |             ]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             $user_data['nickname'] = '用户'.$user_data['sn']; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             $user = User::create($user_data); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             $token = self::createSession($user->id, $post['client']); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //生成会员分销扩展表
 | 
					
						
							|  |  |  |  |             DistributionLogic::createUserDistribution($user->id); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // 生成分销基础信息表
 | 
					
						
							|  |  |  |  |             \app\common\logic\DistributionLogic::add($user->id); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //注册赠送
 | 
					
						
							|  |  |  |  |             self::registerAward($user->id); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             Db::commit(); | 
					
						
							|  |  |  |  |             return ['token' => $token]; | 
					
						
							|  |  |  |  |         }catch(\Exception $e){ | 
					
						
							|  |  |  |  |             Db::rollback(); | 
					
						
							|  |  |  |  |             self::$error = $e->getMessage(); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     public static function registerAward($user_id){ | 
					
						
							|  |  |  |  |         $register_award_integral_status = ConfigServer::get('marketing','register_award_integral_status',0); | 
					
						
							|  |  |  |  |         $register_award_coupon_status = ConfigServer::get('marketing','register_award_coupon_status',0); | 
					
						
							|  |  |  |  |         //赠送积分
 | 
					
						
							|  |  |  |  |         if($register_award_integral_status){ | 
					
						
							|  |  |  |  |             $register_award_integral = ConfigServer::get('marketing','register_award_integral',0); | 
					
						
							|  |  |  |  |             //赠送的积分
 | 
					
						
							|  |  |  |  |             if($register_award_integral > 0){ | 
					
						
							|  |  |  |  |                 $user = User::findOrEmpty($user_id); | 
					
						
							|  |  |  |  |                 $user->user_integral += $register_award_integral; | 
					
						
							|  |  |  |  |                 $user->save(); | 
					
						
							|  |  |  |  |                 AccountLogLogic::AccountRecord($user_id,$register_award_integral,1,AccountLog::register_add_integral,''); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         //注册账号,首次进入首页时领取优惠券
 | 
					
						
							|  |  |  |  |         $register_award_coupon = ConfigServer::get('marketing','register_award_coupon',''); | 
					
						
							|  |  |  |  |         if($register_award_coupon_status && $register_award_coupon){ | 
					
						
							|  |  |  |  |             Cache::tag('register_coupon')->set('register_coupon_'.$user_id,$register_award_coupon); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         // 赠送成长值
 | 
					
						
							|  |  |  |  |         $register_growth = ConfigServer::get('register', 'growth', 0); | 
					
						
							|  |  |  |  |         if($register_growth > 0) { | 
					
						
							|  |  |  |  |             $user = User::findOrEmpty($user_id); | 
					
						
							|  |  |  |  |             $user->user_growth += $register_growth; | 
					
						
							|  |  |  |  |             $user->save(); | 
					
						
							|  |  |  |  |             AccountLogLogic::AccountRecord($user_id,$register_growth,1,AccountLog::register_give_growth,''); | 
					
						
							|  |  |  |  |             // 更新用户会员等级
 | 
					
						
							|  |  |  |  |             LevelLogic::updateUserLevel([$user]); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * 手机号密码登录 | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function mpLogin($post) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         $user = User::field(['id', 'nickname', 'avatar', 'level', 'disable', 'distribution_code']) | 
					
						
							|  |  |  |  |             ->where(['mobile' => $post['mobile']]) | 
					
						
							|  |  |  |  |             ->findOrEmpty()->toArray(); | 
					
						
							|  |  |  |  |         $user['token'] = self::createSession($user['id'], $post['client']); | 
					
						
							|  |  |  |  |         if (empty($user['avatar'])) { | 
					
						
							|  |  |  |  |             $user['avatar'] = UrlServer::getFileUrl(ConfigServer::get('website', 'user_image')); | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             $user['avatar'] = UrlServer::getFileUrl($user['avatar']); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return $user; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * 获取code的url | 
					
						
							|  |  |  |  |      * @param $url | 
					
						
							|  |  |  |  |      * @return string | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function codeUrl($url) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         $config = WeChatServer::getOaConfig(); | 
					
						
							|  |  |  |  |         $app = Factory::officialAccount($config); | 
					
						
							|  |  |  |  |         $response = $app | 
					
						
							|  |  |  |  |             ->oauth | 
					
						
							|  |  |  |  |             ->scopes(['snsapi_userinfo']) | 
					
						
							|  |  |  |  |             ->redirect($url) | 
					
						
							|  |  |  |  |             ->getTargetUrl(); | 
					
						
							|  |  |  |  |         return $response; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /*** | 
					
						
							|  |  |  |  |      * Desc: 微信公众号登录 | 
					
						
							|  |  |  |  |      * @param $post | 
					
						
							|  |  |  |  |      * @return array|string | 
					
						
							|  |  |  |  |      * @throws Exception | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\DataNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\ModelNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\exception\DbException | 
					
						
							|  |  |  |  |      * @throws \think\exception\PDOException | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function oaLogin($post) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         //微信调用
 | 
					
						
							|  |  |  |  |         try { | 
					
						
							|  |  |  |  |             $config = WeChatServer::getOaConfig(); | 
					
						
							|  |  |  |  |             $app = Factory::officialAccount($config); | 
					
						
							|  |  |  |  |             $response = $app | 
					
						
							|  |  |  |  |                 ->oauth | 
					
						
							|  |  |  |  |                 ->scopes(['snsapi_userinfo']) | 
					
						
							|  |  |  |  |                 ->getAccessToken($post['code']); | 
					
						
							|  |  |  |  |             if (!isset($response['openid']) || empty($response['openid'])) { | 
					
						
							|  |  |  |  |                 throw new Exception(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             $user = $app->oauth->user($response); | 
					
						
							|  |  |  |  |             $user = $user->getOriginal(); | 
					
						
							|  |  |  |  |             } catch (Exception $e) { | 
					
						
							|  |  |  |  |                 return $e->getMessage(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         //添加或更新用户
 | 
					
						
							|  |  |  |  |         $user_id = UserAuth::alias('au') | 
					
						
							|  |  |  |  |             ->join('user u', 'au.user_id=u.id') | 
					
						
							|  |  |  |  |             ->where(['u.del' => 0]) | 
					
						
							|  |  |  |  |             ->where(function ($query) use ($user) { | 
					
						
							|  |  |  |  |                 $query->whereOr(['au.openid' => $user['openid']]); | 
					
						
							|  |  |  |  |                 if(isset($user['unionid']) && !empty($user['unionid'])){ | 
					
						
							|  |  |  |  |                     $query->whereOr(['au.unionid' => $user['unionid']]); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             }) | 
					
						
							|  |  |  |  |             ->value('user_id'); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (empty($user_id)) { | 
					
						
							|  |  |  |  |             $user_info = UserServer::createUser($user, Client_::oa); | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             $user_info = UserServer::updateUser($user, Client_::oa, $user_id); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (empty($user_info)) { | 
					
						
							|  |  |  |  |             return '登录失败:user'; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if ($user_info['disable']) { | 
					
						
							|  |  |  |  |             return '该用户被禁用'; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         //创建会话
 | 
					
						
							|  |  |  |  |         $user_info['token'] = self::createSession($user_info['id'], Client_::oa); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         unset($user_info['id']); | 
					
						
							|  |  |  |  |         unset($user_info['disable']); | 
					
						
							|  |  |  |  |         return $user_info->toArray(); | 
					
						
							|  |  |  |  | //        return $user_info;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /*** | 
					
						
							|  |  |  |  |      * app微信登录 | 
					
						
							|  |  |  |  |      * @param $post | 
					
						
							|  |  |  |  |      * @return array|\PDOStatement|string|\think\Model|null | 
					
						
							|  |  |  |  |      * @throws Exception | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\DataNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\db\exception\ModelNotFoundException | 
					
						
							|  |  |  |  |      * @throws \think\exception\DbException | 
					
						
							|  |  |  |  |      * @throws \think\exception\PDOException | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function uinAppLogin($post) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         //微信调用
 | 
					
						
							|  |  |  |  |         try { | 
					
						
							|  |  |  |  |             if (empty($post['openid']) || empty($post['access_token']) || empty($post['client'])){ | 
					
						
							|  |  |  |  |                 throw new Exception('参数缺失'); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //sdk不支持app登录,直接调用微信接口
 | 
					
						
							|  |  |  |  |             $requests = Requests::get('https://api.weixin.qq.com/sns/userinfo?openid=' . 'openid=' . $post['openid'] . '&access_token=' . $post['access_token']); | 
					
						
							|  |  |  |  |             $user = json_decode($requests->body, true); | 
					
						
							|  |  |  |  |         } catch (Exception $e) { | 
					
						
							|  |  |  |  |             return $e->getMessage(); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | //        dump($user);
 | 
					
						
							|  |  |  |  |         //添加或更新用户
 | 
					
						
							|  |  |  |  |         $user_id = UserAuth::alias('au')->join('user u', 'au.user_id=u.id') | 
					
						
							|  |  |  |  |             ->where(['u.del' => 0]) | 
					
						
							|  |  |  |  |             ->where(function ($query) use ($user) { | 
					
						
							|  |  |  |  |                 $query->whereOr(['au.openid' => $user['openid']]) | 
					
						
							|  |  |  |  |                     ->whereOr(['au.unionid' => $user['unionid']]); | 
					
						
							|  |  |  |  |             }) | 
					
						
							|  |  |  |  |             ->value('user_id'); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (empty($user_id)) { | 
					
						
							|  |  |  |  |             $user_info = UserServer::createUser($user, $post['client']); | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             $user_info = UserServer::updateUser($user, $post['client'], $user_id); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (empty($user_info)) { | 
					
						
							|  |  |  |  |             return '登录失败:user'; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if ($user_info['disable']) { | 
					
						
							|  |  |  |  |             return '该用户被禁用'; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         //创建会话
 | 
					
						
							|  |  |  |  |         $user_info['token'] = self::createSession($user_info['id'], $post['client']); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         unset($user_info['id']); | 
					
						
							|  |  |  |  |         unset($user_info['disable']); | 
					
						
							|  |  |  |  |         return $user_info; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     //手机号密码登录
 | 
					
						
							|  |  |  |  |     public static function login($post) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         $user_info = User::field(['id', 'nickname', 'avatar', 'level', 'disable', 'distribution_code']) | 
					
						
							|  |  |  |  |             ->where(['account|mobile' => $post['mobile']]) | 
					
						
							|  |  |  |  |             ->find()->toArray(); | 
					
						
							|  |  |  |  |         $user_info['token'] = self::createSession($user_info['id'], $post['client']); | 
					
						
							|  |  |  |  |         if (empty($user_info['avatar'])) { | 
					
						
							|  |  |  |  |             $user_info['avatar'] = UrlServer::getFileUrl(ConfigServer::get('website', 'user_image')); | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             $user_info['avatar'] = UrlServer::getFileUrl($user_info['avatar']); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return $user_info; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     //退出登录
 | 
					
						
							|  |  |  |  |     public static function logout($user_id, $client) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         return self::expirationSession($user_id, $client); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * 设置会话过期 | 
					
						
							|  |  |  |  |      * @param $user_id | 
					
						
							|  |  |  |  |      * @param $client | 
					
						
							|  |  |  |  |      * @throws \think\Exception | 
					
						
							|  |  |  |  |      * @throws \think\exception\PDOException | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function expirationSession($user_id, $client) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         $time = time(); | 
					
						
							|  |  |  |  |         $token = Db::name('session') | 
					
						
							|  |  |  |  |             ->where(['user_id' => $user_id, 'client' => $client]) | 
					
						
							|  |  |  |  |             ->value('token'); | 
					
						
							|  |  |  |  |         $token_cache = new TokenCache($token); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         $token_cache->del(); | 
					
						
							|  |  |  |  |         return Db::name('session') | 
					
						
							|  |  |  |  |             ->where(['user_id' => $user_id, 'client' => $client]) | 
					
						
							|  |  |  |  |             ->update(['update_time' => $time, 'expire_time' => $time]); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * @notes PC扫码登录, 二维码链接 | 
					
						
							|  |  |  |  |      * @return false|string | 
					
						
							|  |  |  |  |      * @author 段誉 | 
					
						
							|  |  |  |  |      * @date 2021/10/29 11:47 | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function scanCode() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try { | 
					
						
							|  |  |  |  |             $config = WeChatServer::getOpWebConfig(); | 
					
						
							|  |  |  |  |             $appid = $config['app_id']; | 
					
						
							|  |  |  |  |             $domain = request()->domain(); | 
					
						
							|  |  |  |  |             $url = $domain.'/pc/account/login'; | 
					
						
							|  |  |  |  |             $redirect_uri = UrlEncode($url); | 
					
						
							|  |  |  |  |             $state = MD5(time().rand(10000, 99999)); | 
					
						
							|  |  |  |  |             cache($state, $state, 600); //缓存600
 | 
					
						
							|  |  |  |  |             $url = "https://open.weixin.qq.com/connect/qrconnect?appid=$appid&redirect_uri=$redirect_uri&response_type=code&scope=snsapi_login&state=$state#wechat_redirect"; | 
					
						
							|  |  |  |  |             return $url; | 
					
						
							|  |  |  |  |         } catch (\Exception $e) { | 
					
						
							|  |  |  |  |             self::$error = $e->getMessage(); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /** | 
					
						
							|  |  |  |  |      * @notes PC端扫码登录 | 
					
						
							|  |  |  |  |      * @param $params | 
					
						
							|  |  |  |  |      * @return array|false | 
					
						
							|  |  |  |  |      * @author 段誉 | 
					
						
							|  |  |  |  |      * @date 2021/10/29 18:00 | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function scanLogin($params) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try { | 
					
						
							|  |  |  |  |             //验证参数
 | 
					
						
							|  |  |  |  |             if (empty($params['code']) || empty($params['state'])) { | 
					
						
							|  |  |  |  |                 throw new \Exception('参数缺失'); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //验证state
 | 
					
						
							|  |  |  |  |             $state = cache($params['state']); | 
					
						
							|  |  |  |  |             if (empty($state)) { | 
					
						
							|  |  |  |  |                 throw new \Exception('二维码已失效或不存在,请重新扫码'); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             $config = WeChatServer::getOpWebConfig(); | 
					
						
							|  |  |  |  |             $appid = $config['app_id']; | 
					
						
							|  |  |  |  |             $secret = $config['secret']; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //通过code获取access_token,openid,unionid
 | 
					
						
							|  |  |  |  |             $requests = Requests::get('https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid . '&secret=' . $secret . '&code=' . $params['code'] . '&grant_type=authorization_code'); | 
					
						
							|  |  |  |  |             $user_auth = json_decode($requests->body, true); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (empty($user_auth['openid']) || empty($user_auth['access_token'])) { | 
					
						
							|  |  |  |  |                 throw new \think\Exception('获取openID失败'); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //获取用户信息
 | 
					
						
							|  |  |  |  |             $response = Requests::get('https://api.weixin.qq.com/sns/userinfo?access_token='. $user_auth['access_token'] . '&openid=' . $user_auth['openid']); | 
					
						
							|  |  |  |  |             $response = json_decode($response->body, true); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //在系统中查找openid和unionid是否存在
 | 
					
						
							|  |  |  |  |             $user_id = self::getUserByWechatResponse($response); | 
					
						
							|  |  |  |  |             if (empty($user_id)) { | 
					
						
							|  |  |  |  |                 $user_info = UserServer::createUser($response,ClientEnum::pc); | 
					
						
							|  |  |  |  |             } else { | 
					
						
							|  |  |  |  |                 $user_info = UserServer::updateUser($response, ClientEnum::pc, $user_id); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //验证用户信息
 | 
					
						
							|  |  |  |  |             $check_res = self::checkUserInfo($user_info); | 
					
						
							|  |  |  |  |             if (true !== $check_res) { | 
					
						
							|  |  |  |  |                 throw new \Exception($check_res); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //创建会话
 | 
					
						
							|  |  |  |  |             $user_info['token'] = self::createSession($user_info['id'], ClientEnum::pc); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             unset($user_info['id']); | 
					
						
							|  |  |  |  |             unset($user_info['disable']); | 
					
						
							|  |  |  |  |             return $user_info->toArray(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         } catch (\Exception $e) { | 
					
						
							|  |  |  |  |             self::$error = $e->getMessage(); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-26 09:59:15 +08:00
										 |  |  |  |     /** | 
					
						
							|  |  |  |  |      * 第三方接口登录 APPID和appSecret | 
					
						
							|  |  |  |  |      */ | 
					
						
							|  |  |  |  |     public static function apiLogin($post) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         try { | 
					
						
							|  |  |  |  |             if (!$userApi = UserApi::where('app_id', $post['app_id'])->where('app_secret', $post['app_secret'])->find()) { | 
					
						
							|  |  |  |  |                 throw new \Exception('账号错误'); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             $user = User::field(['id', 'nickname', 'avatar', 'level', 'disable', 'distribution_code', 'is_api', 'del']) | 
					
						
							|  |  |  |  |                 ->where(['id' => $userApi['id']]) | 
					
						
							|  |  |  |  |                 ->findOrEmpty()->toArray(); | 
					
						
							|  |  |  |  |             if ($user['disable'] > 0) { | 
					
						
							|  |  |  |  |                 throw new \Exception('账号已禁用'); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if ($user['del'] == 1) { | 
					
						
							|  |  |  |  |                 throw new \Exception('账号异常,请联系管理员'); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if ($user['is_api'] != 1) { | 
					
						
							|  |  |  |  |                 throw new \Exception('账号API授权已关闭'); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             unset($user['del']); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             $user['token'] = self::createSession($user['id'], ClientEnum::api); | 
					
						
							|  |  |  |  |             if (empty($user['avatar'])) { | 
					
						
							|  |  |  |  |                 $user['avatar'] = UrlServer::getFileUrl(ConfigServer::get('website', 'user_image')); | 
					
						
							|  |  |  |  |             } else { | 
					
						
							|  |  |  |  |                 $user['avatar'] = UrlServer::getFileUrl($user['avatar']); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             return $user; | 
					
						
							|  |  |  |  |         } catch (\Exception $e) { | 
					
						
							|  |  |  |  |             self::$error = $e->getMessage(); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-10 14:59:52 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | } |