Files
bsh_sample/app/common/service/UserService.php
T
2025-12-08 17:37:34 +08:00

315 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']);
$name = '微信用户_' . self::generate(8);
// 用户信息
$user = User::firstOrCreate(
['openid' => $wxinfo['openid']],
[
'nickname' => $name,
'unionid' => $wxinfo['unionid'],
'name' => $name,
'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;
}
}