|
|
|
|
|
<?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;
|
|
|
|
|
|
}
|
|
|
|
|
|
$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),
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|