Files
xin-school/app/Http/Controllers/IndexController.php
T
2026-07-15 12:07:32 +08:00

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'));
}
}