128 lines
4.0 KiB
PHP
128 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Requests\UserRegisterRequest;
|
|
use App\Models\UserModel;
|
|
use App\Services\Wechat\MiniProgramService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Modules\AnnoRoute\Attribute\GetRoute;
|
|
use Modules\AnnoRoute\Attribute\PostRoute;
|
|
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
|
use Modules\Common\Trait\RequestJson;
|
|
|
|
#[RequestAttribute('/api', authGuard: 'users')]
|
|
class IndexController
|
|
{
|
|
use RequestJson;
|
|
|
|
/** 获取首页信息 */
|
|
#[GetRoute('/index', false)]
|
|
public function index(): JsonResponse
|
|
{
|
|
$web_setting = site_config('web');
|
|
|
|
return $this->success(compact('web_setting'));
|
|
}
|
|
|
|
/** 用户登录 */
|
|
#[PostRoute('/login', false)]
|
|
public function login(Request $request): JsonResponse
|
|
{
|
|
$credentials = $request->validate([
|
|
'username' => 'required|min:4|alphaDash',
|
|
'password' => 'required|min:4|alphaDash',
|
|
]);
|
|
if (Auth::guard('users')->attempt($credentials, true)) {
|
|
$data = $request->user('users')
|
|
->createToken($credentials['username'])
|
|
->toArray();
|
|
return $this->success($data, __('user.login_success'));
|
|
}
|
|
return $this->error(__('user.login_error'));
|
|
}
|
|
|
|
/** 用户注册 */
|
|
#[PostRoute('/register', false)]
|
|
public function register(UserRegisterRequest $request): JsonResponse
|
|
{
|
|
$data = $request->validated();
|
|
$model = new UserModel;
|
|
$model->username = $data['username'];
|
|
$model->password = password_hash($data['password'], PASSWORD_DEFAULT);
|
|
$model->email = $data['email'];
|
|
if ($model->save()) {
|
|
return $this->success();
|
|
}
|
|
|
|
return $this->error('创建用户失败');
|
|
}
|
|
|
|
/**
|
|
* 小程序登录
|
|
*
|
|
* 仅需 code 完成 openid 换取,首次登录使用默认昵称和头像,
|
|
* 用户信息后续通过编辑接口完善。
|
|
*/
|
|
#[PostRoute('/wx/login', false)]
|
|
public function loginMiniProgram(Request $request, MiniProgramService $miniProgram): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'code' => 'required|string',
|
|
'phoneCode' => 'nullable|string',
|
|
]);
|
|
|
|
// 1. 通过 code 换取 openid、session_key、unionid
|
|
$session = $miniProgram->codeToSession($validated['code']);
|
|
|
|
// 2. 构建用户数据,昵称/头像/性别使用默认值
|
|
$userData = [
|
|
'openid' => $session['openid'],
|
|
'unionid' => $session['unionid'] ?? '',
|
|
'username' => 'wx_'.uniqid(),
|
|
'nickname' => '微信用户',
|
|
'avatar' => '',
|
|
'gender' => 0,
|
|
'password' => '',
|
|
];
|
|
|
|
// 3. 解密手机号
|
|
if (! empty($validated['phoneCode'])) {
|
|
try {
|
|
$phoneInfo = $miniProgram->getPhoneNumber($validated['phoneCode']);
|
|
$userData['mobile'] = $phoneInfo['phone_info']['purePhoneNumber'] ?? '';
|
|
} catch (\Throwable) {
|
|
// 手机号解密失败不阻塞登录
|
|
}
|
|
}
|
|
|
|
// 4. 查找或创建用户
|
|
$user = UserModel::firstOrCreate(
|
|
['openid' => $userData['openid']],
|
|
$userData
|
|
);
|
|
|
|
// 5. 更新已有用户缺失的手机号和 unionid
|
|
$needUpdate = false;
|
|
foreach (['mobile', 'unionid'] as $field) {
|
|
if (! empty($userData[$field]) && empty($user->$field)) {
|
|
$user->$field = $userData[$field];
|
|
$needUpdate = true;
|
|
}
|
|
}
|
|
if ($needUpdate) {
|
|
$user->save();
|
|
}
|
|
|
|
// 6. 创建 Sanctum token
|
|
$token = $user->createToken($user->username)->toArray();
|
|
|
|
return $this->success([
|
|
'token' => $token['plainTextToken'],
|
|
'user' => $user->toArray(),
|
|
], __('user.login_success'));
|
|
}
|
|
}
|