feat: add note module and route fixes

This commit is contained in:
nepiedg
2026-04-17 07:48:44 +00:00
parent 866ddb046b
commit 84e1c0daac
25 changed files with 2196 additions and 38 deletions
+164
View File
@@ -0,0 +1,164 @@
<?php
declare(strict_types=1);
namespace app\note\service;
use app\api\common\Jwt;
use app\note\model\NoteUser;
/**
* note 模块认证服务
*/
class AuthService
{
/**
* 微信小程序登录
*
* @param string $code
* @param string|null $nickname
* @param string|null $avatarUrl
* @return array
* @throws \Exception
*/
public function wechatLogin(string $code, ?string $nickname = null, ?string $avatarUrl = null): array
{
$session = $this->fetchWechatSession($code);
$openid = trim((string) ($session['openid'] ?? ''));
if ($openid === '') {
throw new \Exception('微信登录失败,未获取到 openid', 500);
}
$now = time();
$user = NoteUser::findByOpenid($openid);
$isNewUser = false;
if (!$user) {
$user = new NoteUser();
$user->openid = $openid;
$user->created_at = $now;
$isNewUser = true;
}
if (!$isNewUser && (int) $user->status === 0) {
throw new \Exception('小程序账号已被禁用', 403);
}
$user->unionid = (string) ($session['unionid'] ?? '');
$user->session_key = (string) ($session['session_key'] ?? '');
$user->nickname = $nickname !== null ? trim($nickname) : (string) $user->nickname;
$user->avatar_url = $avatarUrl !== null ? trim($avatarUrl) : (string) $user->avatar_url;
$user->status = 1;
$user->last_login_ip = (string) request()->ip();
$user->last_login_time = $now;
$user->updated_at = $now;
$user->deleted_at = 0;
if (!$user->save()) {
throw new \Exception('小程序用户登录保存失败', 500);
}
$token = Jwt::encode([
'userid' => (int) $user->id,
'guard' => 'note',
'openid' => $user->openid,
]);
$refreshToken = Jwt::encode([
'userid' => (int) $user->id,
'guard' => 'note',
'type' => 'refresh',
'openid' => $user->openid,
]);
return [
'token' => $token,
'refresh_token' => $refreshToken,
'expires_in' => config('jwt.expire', 604800),
'user' => [
'id' => (int) $user->id,
'member_id' => (int) ($user->member_id ?? 0),
'openid' => (string) $user->openid,
'nickname' => (string) $user->nickname,
'avatar_url' => (string) $user->avatar_url,
'mobile' => (string) $user->mobile,
'is_new_user' => $isNewUser,
],
];
}
/**
* 获取当前小程序用户信息
*
* @param int $noteUserId
* @return array
* @throws \Exception
*/
public function getUserInfo(int $noteUserId): array
{
$user = NoteUser::findActiveById($noteUserId);
if (!$user) {
throw new \Exception('小程序用户不存在', 404);
}
return [
'id' => (int) $user->id,
'member_id' => (int) ($user->member_id ?? 0),
'openid' => (string) $user->openid,
'nickname' => (string) $user->nickname,
'avatar_url' => (string) $user->avatar_url,
'mobile' => (string) $user->mobile,
'status' => (int) $user->status,
'last_login_time' => (int) $user->last_login_time,
'created_at' => (int) $user->created_at,
];
}
/**
* 请求微信 code2Session
*
* @param string $code
* @return array
* @throws \Exception
*/
private function fetchWechatSession(string $code): array
{
$appId = (string) env('WECHAT_MINI_APPID', '');
$appSecret = (string) env('WECHAT_MINI_SECRET', '');
if ($appId === '' || $appSecret === '') {
throw new \Exception('缺少微信小程序配置 WECHAT_MINI_APPID / WECHAT_MINI_SECRET', 500);
}
$url = sprintf(
'https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code',
urlencode($appId),
urlencode($appSecret),
urlencode($code)
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($response === false || $response === '' || $error) {
throw new \Exception('微信登录请求失败', 502);
}
$data = json_decode($response, true);
if (!is_array($data)) {
throw new \Exception('微信登录响应解析失败', 502);
}
if (!empty($data['errcode'])) {
throw new \Exception(sprintf('微信登录失败:%s', (string) ($data['errmsg'] ?? 'unknown error')), 400);
}
return $data;
}
}