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.

283 lines
9.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers\Admin;
use App\Helpers\ApiResponse;
use App\Helpers\ResponseCode;
use App\Helpers\StarterResponseCode;
use App\Http\Controllers\Controller;
use App\Models\Admin;
use App\Models\Config;
use App\Models\OperateLog;
use App\Models\Permission;
use App\Models\RoleHasPermission;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
class AuthController extends Controller
{
use ApiResponse;
public $guard = "admin";
/**
* Create a new AuthController instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('sanctum.jwt:admin', ['except' => ['login', 'sendSms', 'smsLogin']]);
}
/**
* Create a new AuthController instance.
*
* @return void
*/
public function guard()
{
return auth()->guard($this->guard);
}
/**
* @OA\Post(
* path="/api/admin/auth/login",
* tags={"后台管理"},
* summary="用户名密码登录",
* description="",
* @OA\Parameter(name="username", in="query", @OA\Schema(type="string"), required=true, description="用户名"),
* @OA\Parameter(name="password", in="query", @OA\Schema(type="string"), required=true, description="密码"),
* @OA\Response(
* response="200",
* description="用户名密码登录"
* )
* )
*/
public function login()
{
$credentials = request(['username', 'password']);
if (!$token = $this->guard()->attempt($credentials)) {
return $this->fail(StarterResponseCode::LOGIN_FAIL);
}
$user = $this->guard()->user();
$token = $user->createToken("token")->plainTextToken;
// 加日志
OperateLog::addLogs($user, "用户[{$user->name}]登陆成功");
return $this->respondWithToken($token);
}
/**
* @OA\Post(
* path="/api/admin/auth/me",
* tags={"后台管理"},
* summary="获取用户基本信息",
* description="",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="获取用户基本信息"
* )
* )
*/
public function me()
{
$user = Admin::with('department')->find($this->guard()->user()->id);
return $this->success($user);
}
/**
* @OA\Post(
* path="/api/admin/auth/logout",
* tags={"后台管理"},
* summary="退出登录",
* description="",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="退出登录"
* )
* )
*/
public function logout()
{
$user = $this->guard()->user();
$user->tokens()->delete();
$this->guard()->logout();
// 加日志
OperateLog::addLogs($user, "用户[$user->name]退出登陆");
return $this->success(["msg" => "登出成功"]);
}
/**
* @OA\Get(
* path="/api/admin/auth/permissions",
* tags={"后台管理"},
* summary="获取权限菜单",
* description="",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="获取权限菜单"
* )
* )
*/
public function getPermissions()
{
$admin = $this->guard()->user();
$admin_permissions = $admin->getAllPermissions();
$all_permissions = (new Permission())->get()->toArray();
$permission_has_url_ids = $admin_permissions->filter(function ($item) {
return $item->url && $item->visible ? true : false;
})->pluck("id")->toArray();
foreach ($admin_permissions as $admin_permission) {
$pids = get_pid($all_permissions, $admin_permission->id, "pid", $permission_has_url_ids);
foreach ($pids as $pid) {
if (in_array($pid, $permission_has_url_ids)) continue;
$permission_has_url_ids[] = $pid;
}
}
$admin_permissions = new Permission();
$admin_permissions = $admin_permissions->whereIn("id", $permission_has_url_ids);
$admin_permissions = $admin_permissions->orderBy("sortnumber")->get();
$admin_permissions = $admin_permissions->toArray();
$roleIds = $this->guard()->user()->roles->pluck('id')->toArray();
foreach ($admin_permissions as &$item) {
$item['has_auth_node_tags'] = [];
$has_auth_node_tags = RoleHasPermission::whereIn('role_id', $roleIds)
->where('permission_id', $item['id'])
->get()->implode('auth_node_tags', ',');
if ($has_auth_node_tags) {
$item['has_auth_node_tags'] = array_filter(array_unique(explode(',', $has_auth_node_tags)));
}
}
$admin_permissions = array2tree($admin_permissions);
return response()->json($admin_permissions);
}
/**
* @OA\Get(
* path="/api/admin/auth/sms-login",
* tags={"后台管理"},
* summary="验证码登陆",
* description="",
* @OA\Parameter(name="mobile", in="query", @OA\Schema(type="string"), required=true, description="手机号"),
* @OA\Parameter(name="code", in="query", @OA\Schema(type="string"), required=true, description="验证码"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description=""
* )
* )
*/
public function smsLogin()
{
$all = \request()->all();
$messages = [
'mobile.required' => '手机号必填',
'mobile.numeric' => '手机号格式错误',
'code' => '验证码必填',
];
$validator = Validator::make($all, [
'mobile' => 'required|numeric',
'code' => 'required',
], $messages);
if ($validator->fails()) {
return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$key = 'sms_admin_' . $all['mobile'];
$check = Cache::get($key);
if (empty($check)) return $this->fail([ResponseCode::ERROR_BUSINESS, '请先发送验证码']);
if ($check['code'] != $all['code']) return $this->fail([ResponseCode::ERROR_BUSINESS, '验证码错误']);
// 判断手机号是否存在
$admin = Admin::where('mobile', $all['mobile'])->first();
if (empty($admin)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '用户不存在']);
}
$token = $admin->createToken("token")->plainTextToken;
// 加日志
OperateLog::addLogs($admin, "用户[{$admin->name}]短信登陆成功");
return $this->respondWithToken($token);
}
/**
* @OA\Get (
* path="/api/admin/auth/send-sms",
* tags={"后台管理"},
* summary="短信发送",
* description="",
* @OA\Parameter(name="mobile", in="query", @OA\Schema(type="string"), required=true, description="手机号"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description=""
* )
* )
*/
public function sendSms()
{
$all = \request()->all();
$messages = [
'mobile.required' => '手机号必填',
'mobile.numeric' => '手机号格式错误',
];
$validator = Validator::make($all, [
'mobile' => 'required|numeric',
], $messages);
if ($validator->fails()) {
return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$key = 'sms_admin_' . $all['mobile'];
$check = Cache::get($key);
if (isset($check) && time() - $check['time'] <= 60) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '请勿频繁发送']);
}
// 用户检测
$admin = Admin::where('mobile', $all['mobile'])->first();
if (empty($admin)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '用户不存在']);
}
$code = rand(1000, 9999);
$smsSign = Config::getValueByKey('sms_sign');
$content = "{$smsSign}验证码{$code}您正在登陆苏州科技商学院信息化系统请在5分钟内完成验证。";
$result = ymSms($all['mobile'], $content);
if ($result) {
// 缓存
Cache::put($key, ['code' => $code, 'time' => time()], 300);
return $this->success("发送成功");
}
return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, "发送失败"]);
}
/**
* Get the token array structure.
*
* @param string $token
*
* @return \Illuminate\Http\JsonResponse
*/
protected function respondWithToken($token)
{
$ttl = config("sanctum.expiration");
if ($ttl) {
$expires_in = $ttl * 60;
} else {
$expires_in = null;
}
return $this->success([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => $expires_in
]);
}
}