You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.4 KiB

2 weeks ago
<?php
namespace App\Http\Controllers\Miniapp;
use App\Http\Controllers\Controller;
use App\Models\MiniappUser;
use App\Services\WeChatMiniProgramService;
use App\Support\ApiResponse;
use App\Support\Miniapp\MiniappPresenter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class AuthController extends Controller
{
use ApiResponse;
public function __construct(protected WeChatMiniProgramService $wechat) {}
public function wechatLogin(Request $request): JsonResponse
{
$data = $request->validate([
'code' => ['required', 'string', 'max:128'],
'nickname' => ['nullable', 'string', 'max:64'],
'avatar_url' => ['nullable', 'string', 'max:512'],
]);
try {
$session = $this->wechat->codeToSession($data['code']);
} catch (\Throwable $e) {
return $this->fail($e->getMessage(), 422);
}
$user = MiniappUser::query()->firstOrNew(['openid' => $session['openid']]);
if ($session['unionid']) {
$user->unionid = $session['unionid'];
}
if (! empty($data['nickname'])) {
$user->nickname = $data['nickname'];
}
if (! empty($data['avatar_url'])) {
$user->avatar_url = $data['avatar_url'];
}
if (! $user->exists) {
$user->status = 1;
5 days ago
$displayName = $data['nickname'] ?? '微信用户';
$user->name = $displayName;
if (empty($user->nickname)) {
$user->nickname = $displayName;
}
2 weeks ago
}
$user->save();
if ((int) $user->status !== 1) {
return $this->fail('账号已停用', 403);
}
return $this->ok($this->issueToken($user));
}
/**
* 本地开发专用:浏览器 H5 调试时无法调用 wx.login使用此接口模拟登录。
*/
public function devLogin(Request $request): JsonResponse
{
if (! app()->environment('local')) {
return $this->fail('仅 local 环境可用', 404);
}
$data = $request->validate([
'nickname' => ['nullable', 'string', 'max:64'],
'avatar_url' => ['nullable', 'string', 'max:512'],
]);
$openid = 'dev_'.Str::lower(Str::random(24));
$user = MiniappUser::query()->create([
'openid' => $openid,
'unionid' => null,
'nickname' => $data['nickname'] ?? '本地调试用户',
'avatar_url' => $data['avatar_url'] ?? null,
'name' => $data['nickname'] ?? '本地调试用户',
'status' => 1,
]);
return $this->ok($this->issueToken($user));
}
public function me(Request $request): JsonResponse
{
/** @var MiniappUser $user */
$user = $request->user();
return $this->ok(MiniappPresenter::userPayload($user));
}
public function logout(Request $request): JsonResponse
{
$request->user()?->currentAccessToken()?->delete();
return $this->ok(null, '已退出');
}
/** @return array<string, mixed> */
protected function issueToken(MiniappUser $user): array
{
$user->tokens()->where('name', 'miniapp-api')->delete();
$token = $user->createToken('miniapp-api')->plainTextToken;
return [
'token' => $token,
'token_type' => 'Bearer',
'user' => MiniappPresenter::userPayload($user),
];
}
}