314 lines
9.5 KiB
PHP
314 lines
9.5 KiB
PHP
<?php
|
|
|
|
namespace app\common\service;
|
|
|
|
use app\common\logic\AuthLogic;
|
|
use app\common\validate\UserValidate;
|
|
use app\common\traits\crud\CrudServiceTrait;
|
|
use app\common\model\User;
|
|
use app\common\logic\UserLogic;
|
|
use app\common\utils\Jwt;
|
|
use support\exception\BusinessException;
|
|
use support\Request;
|
|
|
|
class UserService
|
|
{
|
|
|
|
use CrudServiceTrait;
|
|
|
|
/**
|
|
* 指定当前要操作的模型
|
|
*/
|
|
protected string $modelClass = User::class;
|
|
|
|
|
|
protected $logic;
|
|
|
|
// 字符集配置
|
|
protected static $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
|
|
public function __construct()
|
|
{
|
|
$this->logic = (new UserLogic());
|
|
}
|
|
|
|
/**
|
|
* 验证器
|
|
*/
|
|
protected $validator = UserValidate::class;
|
|
|
|
/**
|
|
* 获取验证器
|
|
*/
|
|
public function getValidator()
|
|
{
|
|
return new $this->validator;
|
|
}
|
|
|
|
/**
|
|
* 获取微信二维码
|
|
*/
|
|
public function makeQrUrl()
|
|
{
|
|
$wechat = new WechatService();
|
|
return $wechat->makeQrUrl();
|
|
}
|
|
|
|
/**
|
|
* 获取用户信息
|
|
*/
|
|
public function userInfo(string $code, string $state)
|
|
{
|
|
$logic = new UserLogic();
|
|
$accessToken = $logic->getAccessToken($code, $state);
|
|
// $accessToken['openid'] = 'op9DT6xBzVF05dypmQ2JsM5DP6yw';
|
|
// $accessToken['unionid'] = 'o04nT6-St_2MZR6VRduYEwiicmiA';
|
|
$userInfo = $logic->checkUser($accessToken['openid'], $accessToken['unionid']);
|
|
|
|
if ($userInfo === false) {
|
|
return [
|
|
'is_bind' => false,
|
|
'access_token' => $accessToken['access_token'],
|
|
'openid' => $accessToken['openid'],
|
|
'unionid' => $accessToken['unionid'],
|
|
];
|
|
}
|
|
|
|
$jwt = new Jwt();
|
|
$token = $jwt->generateToken($logic->buildJwtPayload($userInfo));
|
|
$refreshToken = (new AuthLogic())->generateRefreshToken($userInfo->id, 'board');
|
|
return array_merge($userInfo->toArray(), ['access_token' => $token, 'is_bind' => true, 'refresh_token'=> $refreshToken, 'expires_in' => config('jwt.jwt_expiration')]);
|
|
}
|
|
|
|
|
|
/**
|
|
* 获取用户信息(包括菜单和权限)
|
|
*/
|
|
public function getUserInfo(int $uid)
|
|
{
|
|
$user = $this->logic->userInfo($uid);
|
|
$ossservice = new OssService();
|
|
$user['avatar_pull'] = $user->avatar;
|
|
if(strpos($user->avatar, 'http') === false && !empty($user->avatar)){
|
|
$user['avatar_pull'] = $ossservice->generatePrivateUrl($user->avatar);
|
|
// $user['avatar_pull'] = '/proxy/ossurl?file='.$user->avatar;
|
|
}
|
|
return [
|
|
'user' => [
|
|
'id' => $user->id,
|
|
'name' => $user->name,
|
|
'avatar' => $user->avatar,
|
|
'avatar_pull' => $user['avatar_pull'],
|
|
'mobile' => $user->mobile,
|
|
'email' => $user->email,
|
|
'nickname' => $user->nickname,
|
|
'status' => $user->status,
|
|
'openid' => $user->openid,
|
|
'unionid' => $user->unionid,
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 绑定用户
|
|
*
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
public function bindUser(array $data)
|
|
{
|
|
$logic = new UserLogic();
|
|
$wechat = [
|
|
'access_token' => $data['access_token'],
|
|
'openid' => $data['openid'],
|
|
];
|
|
$wechatUserInfo = $logic->getWechatUserInfo($wechat);
|
|
$uData = [
|
|
'nickname' => $wechatUserInfo['nickname'],
|
|
'avatar' => $wechatUserInfo['headimgurl'],
|
|
'unionid' => $wechatUserInfo['unionid'],
|
|
'openid' => $wechatUserInfo['openid'],
|
|
'name' => $data['name'],
|
|
'mobile' => $data['mobile'],
|
|
'sn' => $data['sn'],
|
|
'password' => $data['password'],
|
|
];
|
|
$userinfo = $logic->bindUser($uData);
|
|
if ($userinfo === false) {
|
|
throw new BusinessException('未查到用户信息');
|
|
}
|
|
|
|
$jwt = new Jwt();
|
|
$refreshToken = (new AuthLogic())->generateRefreshToken($userinfo->id, 'board');
|
|
return array_merge($userinfo->toArray(), [
|
|
'access_token' => $jwt->generateToken($logic->buildJwtPayload($userinfo)),
|
|
'is_bind' => true,
|
|
'refresh_token'=> $refreshToken,
|
|
'expires_in' => config('jwt.jwt_expiration')
|
|
]);
|
|
}
|
|
|
|
|
|
/**
|
|
* 获取用户列表
|
|
*/
|
|
public function getList()
|
|
{
|
|
return $this->logic->getList();
|
|
}
|
|
|
|
/**
|
|
* 修改用户密码
|
|
*/
|
|
public function savePassword(int $uid, array $data)
|
|
{
|
|
// 对密码进行哈希处理
|
|
$password = $data['password'];
|
|
$user = User::find($uid);
|
|
if (!password_verify($password, $user->password)) {
|
|
throw new BusinessException('密码错误');
|
|
}
|
|
|
|
$user = $this->logic->savePassword($uid,$data);
|
|
return $user;
|
|
}
|
|
|
|
/**
|
|
* 修改用户密码
|
|
*/
|
|
public function save(int $uid, array $data)
|
|
{
|
|
// 对密码进行哈希处理
|
|
$user = User::find($uid);
|
|
$keysToKeep = ['name', 'nickname', 'avatar'];
|
|
|
|
$data = array_intersect_key($data, array_flip($keysToKeep));
|
|
|
|
$user = $user->update($data);
|
|
return $user;
|
|
}
|
|
|
|
/**
|
|
* 获取微信小程序用户信息(登录及获取手机号)
|
|
*/
|
|
public function wechatLogin(string $loginCode, string $phoneCode)
|
|
{
|
|
$logic = new UserLogic();
|
|
//$accessToken = $logic->getAccessToken($code, $state);
|
|
|
|
$session = $logic->miniCode2Session($loginCode);
|
|
if (!isset($session['openid'])) {
|
|
throw new BusinessException('登录失败');
|
|
// return json(['code'=>0, 'msg'=>'登录失败', 'data'=>$session]);
|
|
}
|
|
|
|
$openid = $session['openid'];
|
|
|
|
$tokenData = $logic->getMiniAccessToken();
|
|
$access_token = $tokenData['access_token'];
|
|
|
|
// 换手机号
|
|
$phoneData = $logic->getMiniPhoneNumber($access_token, $phoneCode);
|
|
|
|
if (!isset($phoneData['phone_info']['phoneNumber'])) {
|
|
throw new BusinessException('获取手机号失败');
|
|
// return json(['code'=>0, 'msg'=>'获取手机号失败', 'data'=>$phoneData]);
|
|
}
|
|
|
|
$phone = $phoneData['phone_info']['phoneNumber'];
|
|
|
|
$user = User::firstOrCreate(['phone' => $phone], [
|
|
'openid' => $openid
|
|
]);
|
|
|
|
// $userInfo = $logic->checkUser($accessToken['openid'], $accessToken['unionid']);
|
|
//
|
|
// if ($userInfo === false) {
|
|
// return [
|
|
// 'is_bind' => false,
|
|
// 'access_token' => $accessToken['access_token'],
|
|
// 'openid' => $accessToken['openid'],
|
|
// 'unionid' => $accessToken['unionid'],
|
|
// ];
|
|
// }
|
|
|
|
$jwt = new Jwt();
|
|
$JwtPayload = $logic->buildJwtPayload($user);
|
|
$JwtPayload['exp'] = $JwtPayload['exp'] + (86400 * 30);
|
|
$token = $jwt->generateToken($JwtPayload);
|
|
$refreshToken = (new AuthLogic())->generateRefreshToken($user->id, 'info');
|
|
return array_merge($user->toArray(), ['access_token' => $token, 'is_bind' => true, 'refresh_token'=> $refreshToken, 'expires_in' => config('jwt.jwt_expiration')]);
|
|
}
|
|
|
|
|
|
/**
|
|
* 小程序登录
|
|
*/
|
|
public function miniappLogin(array $data)
|
|
{
|
|
$logic = new UserLogic();
|
|
$wechatService = new WechatService();
|
|
$wxinfo = $wechatService->xcxOpenid($data['code']);
|
|
|
|
// 用户信息
|
|
$user = User::firstOrCreate(
|
|
['openid' => $wxinfo['openid']],
|
|
[
|
|
'nickname' => '微信用户_'.$wxinfo['openid'],
|
|
'unionid' => $wxinfo['unionid'],
|
|
'name' => '微信用户_' . self::generate(8),
|
|
'avatar' => 'bsh_datax/user/20251021/a4ee815405a1506abeec1af0f738f70f_68f6e76514b66.jpg'
|
|
]
|
|
);
|
|
|
|
|
|
$jwt = new Jwt();
|
|
$JwtPayload = $logic->buildJwtPayload($user);
|
|
$JwtPayload['exp'] = $JwtPayload['exp'] + (86400 * 30);
|
|
$token = $jwt->generateToken($JwtPayload);
|
|
$refreshToken = (new AuthLogic())->generateRefreshToken($user->id, 'info');
|
|
|
|
return array_merge($user->toArray(), ['token' => $token, 'is_bind' => true, 'refresh_token'=> $refreshToken, 'expires_in' => config('jwt.jwt_expiration')]);
|
|
}
|
|
|
|
/**
|
|
* 获取手机号
|
|
*/
|
|
public function miniappPhoneNumber(array $data,Request $request)
|
|
{
|
|
// 手机号
|
|
$wechatService = new WechatService();
|
|
$wxinfo = $wechatService->xcxPhoneNumber($data['phone_code']);
|
|
|
|
$uinfo = User::where('id', $request->user->uid)->first();
|
|
$uinfo->mobile = $wxinfo['phone_info']['phoneNumber'];
|
|
$uinfo->save();
|
|
|
|
return $wxinfo;
|
|
}
|
|
|
|
/**
|
|
* 生成随机字符串编码
|
|
*
|
|
* @param int $length 字符串长度
|
|
* @param bool $uppercaseOnly 是否只使用大写字母
|
|
* @return string
|
|
*/
|
|
public static function generate(int $length = 8, bool $uppercaseOnly = false): string
|
|
{
|
|
$characters = self::$characters;
|
|
|
|
if ($uppercaseOnly) {
|
|
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
}
|
|
|
|
$charactersLength = strlen($characters);
|
|
$randomString = '';
|
|
|
|
for ($i = 0; $i < $length; $i++) {
|
|
$randomString .= $characters[random_int(0, $charactersLength - 1)];
|
|
}
|
|
|
|
return $randomString;
|
|
}
|
|
} |