Commit 13d116a8 authored by UtopiaXC's avatar UtopiaXC

🚆 重写迁移脚本,重构错误代码结构,完成登录

parent f0185086
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -6,8 +6,14 @@ use App\Http\Utils\R; ...@@ -6,8 +6,14 @@ use App\Http\Utils\R;
use App\Models\Users\User; use App\Models\Users\User;
use App\Models\Users\UserProfile; use App\Models\Users\UserProfile;
use Exception; use Exception;
use HTTP_CODE;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Predis\Connection\ConnectionException;
use RedisCacheKey;
use Webpatser\Uuid\Uuid; use Webpatser\Uuid\Uuid;
class UserController extends Controller class UserController extends Controller
...@@ -15,38 +21,73 @@ class UserController extends Controller ...@@ -15,38 +21,73 @@ class UserController extends Controller
function register(Request $request) function register(Request $request)
{ {
if (!CaptchaController::check_captcha($request->get("captcha"), $request->cookie(app()->getNamespace() . "session"))) { if (!CaptchaController::check_captcha($request->get("captcha"), $request->cookie(app()->getNamespace() . "session"))) {
return R::error("403001","验证码错误"); return R::error(HTTP_CODE::UNAUTHORIZED_CAPTCHA);
} }
try { try {
if (!$request->get("email") || !$request->get("user_name") || !$request->get("password")) {
return R::error(HTTP_CODE::NOT_ACCEPT_PARAMS_CONTENT_WRONG);
}
$email = $request->get("email"); $email = $request->get("email");
$user_name=$request->get("user_name"); $user_name = $request->get("user_name");
$password=password_hash($request->get("password"),PASSWORD_DEFAULT); $password = password_hash($request->get("password"), PASSWORD_DEFAULT);
$user=User::query() $user = User::query()
->where("user_name",$user_name) ->where("user_name", $user_name)
->orWhere("user_name",$email) ->orWhere("user_name", $email)
->get(); ->get();
if (sizeof($user)!=0){ if (sizeof($user) != 0) {
return R::error("403002","该邮箱或用户名已被注册"); return R::error(HTTP_CODE::REFUSED_REGISTER_EXISTS);
} }
$user=new User(); $user = new User();
$user->id=Uuid::generate(); $user->id = Uuid::generate();
$user->user_name=$user_name; $user->user_name = $user_name;
$user->user_email=$email; $user->user_email = $email;
$user->user_password=$password; $user->user_password = $password;
$user->user_type=\UserTypeEnum::NORMAL; $user->user_type = \UserTypeEnum::NORMAL;
$user->user_status=\UserStatusEnum::NOT_VERITY; $user->user_status = \UserStatusEnum::NOT_VERITY;
$user_profile=new UserProfile(); $user_profile = new UserProfile();
$user_profile->id=Uuid::generate(); $user_profile->id = Uuid::generate();
$user_profile->user_id=$user->id; $user_profile->user_id = $user->id;
DB::beginTransaction(); DB::beginTransaction();
$user->save(); $user->save();
$user_profile->save(); $user_profile->save();
DB::commit(); DB::commit();
}catch (Exception $e){ } catch (Exception $e) {
DB::rollBack(); DB::rollBack();
return R::error("500001","用户数据保存错误"); return R::error(HTTP_CODE::INTERNAL_SERVER_ERROR);
} }
return R::ok(); return R::ok();
} }
function login(Request $request)
{
if (!CaptchaController::check_captcha($request->get("captcha"), $request->cookie(app()->getNamespace() . "session"))) {
return R::error(HTTP_CODE::UNAUTHORIZED_CAPTCHA);
}
$username = $request->get("user");
$password = $request->get("password");
if (!$username || !$password) {
return R::error(HTTP_CODE::NOT_ACCEPT_PARAMS_CONTENT_WRONG);
}
$user = User::query()
->where("user_name", $username)
->orWhere("user_email", $username)
->get();
if (sizeof($user) == 0) {
return R::error(HTTP_CODE::REFUSED_LOGIN_NO_REGISTER);
}
if (!password_verify($password, $user[0]->user_password)) {
return R::error(HTTP_CODE::REFUSED_LOGIN_WRONG, $user[0]->user_password);
}
$token = md5($user[0]->id . md5(microtime(true)));
$cookie = Cookie::make(\CookieKey::USER_TOKEN, $token, 60 * 24 * 30);
$expiredMinutes = 60 * 24 * 30;
$expiredAt = now()->addMinute($expiredMinutes);
try {
Redis::setex(RedisCacheKey::USER_TOKEN . $token, $expiredMinutes * 60, $user[0]);
} catch (ConnectionException $e) {
Cache::put(RedisCacheKey::USER_TOKEN . $token, $user[0], $expiredAt);
return R::ok()->withCookie($cookie);
}
return R::ok()->withCookie($cookie);
}
} }
...@@ -39,12 +39,14 @@ class Kernel extends HttpKernel ...@@ -39,12 +39,14 @@ class Kernel extends HttpKernel
\Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class, \App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\EncryptCookies::class
], ],
'api' => [ 'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api', 'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\EncryptCookies::class
], ],
]; ];
...@@ -56,7 +58,6 @@ class Kernel extends HttpKernel ...@@ -56,7 +58,6 @@ class Kernel extends HttpKernel
* @var array * @var array
*/ */
protected $routeMiddleware = [ protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class,
......
<?php
namespace App\Http\Middleware\View;
use Closure;
use Illuminate\Http\Request;
class SiteProfileMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
return $next($request);
}
}
...@@ -4,6 +4,8 @@ namespace App\Http\Middleware\View; ...@@ -4,6 +4,8 @@ namespace App\Http\Middleware\View;
use Closure; use Closure;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;
use Predis\Connection\ConnectionException;
class UserAuthMiddleware class UserAuthMiddleware
{ {
...@@ -16,6 +18,19 @@ class UserAuthMiddleware ...@@ -16,6 +18,19 @@ class UserAuthMiddleware
*/ */
public function handle(Request $request, Closure $next) public function handle(Request $request, Closure $next)
{ {
$token = $request->cookie(\CookieKey::USER_TOKEN);
if (!$token) {
$request->attributes->add([\HeaderKey::LOGIN_STATUS => false]);
}
try {
$user = json_decode(Redis::get(\RedisCacheKey::USER_TOKEN . $token), true);
} catch (ConnectionException $e) {
$user = json_decode(\Cache::get(\RedisCacheKey::USER_TOKEN . $token), true);
}
if (!$user)
$request->attributes->add([\HeaderKey::LOGIN_STATUS => false]);
else
$request->attributes->add([\HeaderKey::LOGIN_STATUS => true,\HeaderKey::USER_INFO=>$user]);
return $next($request); return $next($request);
} }
} }
...@@ -15,17 +15,17 @@ class R extends BaseController ...@@ -15,17 +15,17 @@ class R extends BaseController
static public function ok($data = []) static public function ok($data = [])
{ {
return response()->json([ return response()->json([
'code' => 200, 'code' => HTTP_CODE::SUCCESS,
'message' => "success", 'message' => trans('http_code.code')[HTTP_CODE::SUCCESS],
'data' => $data, 'data' => $data,
]); ]);
} }
static public function error($code,$message, $data = []) static public function error($code, $data = [])
{ {
return response()->json([ return response()->json([
'code' => $code, 'code' => $code,
'message' => $message, 'message' => trans('http_code.code')[(int)$code],
'data' => $data, 'data' => $data,
]); ]);
} }
......
...@@ -6,7 +6,24 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; ...@@ -6,7 +6,24 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
/** /**
* App\Models\System\SiteProfile
* *
* @property string $id
* @property string $profile_type
* @property string $profile_description
* @property string $profile_content
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder|SiteProfile newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|SiteProfile newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|SiteProfile query()
* @method static \Illuminate\Database\Eloquent\Builder|SiteProfile whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|SiteProfile whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|SiteProfile whereProfileContent($value)
* @method static \Illuminate\Database\Eloquent\Builder|SiteProfile whereProfileDescription($value)
* @method static \Illuminate\Database\Eloquent\Builder|SiteProfile whereProfileType($value)
* @method static \Illuminate\Database\Eloquent\Builder|SiteProfile whereUpdatedAt($value)
* @mixin \Eloquent
*/ */
class SiteProfile extends Model class SiteProfile extends Model
{ {
......
...@@ -5,6 +5,30 @@ namespace App\Models\Users; ...@@ -5,6 +5,30 @@ namespace App\Models\Users;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
/**
* App\Models\Users\User
*
* @property string $id
* @property string $user_name
* @property string $user_email
* @property string $user_password
* @property string $user_type
* @property string $user_status
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|User newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|User query()
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserEmail($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserName($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserPassword($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserStatus($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserType($value)
* @mixin \Eloquent
*/
class User extends Model class User extends Model
{ {
use HasFactory; use HasFactory;
......
...@@ -5,6 +5,38 @@ namespace App\Models\Users; ...@@ -5,6 +5,38 @@ namespace App\Models\Users;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
/**
* App\Models\Users\UserProfile
*
* @property string $id
* @property string $user_id
* @property string|null $user_nickname
* @property string|null $user_avatar
* @property string|null $user_sex
* @property string|null $user_birthday
* @property string|null $user_job
* @property string|null $user_city
* @property string|null $user_main_page
* @property string|null $user_github
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile query()
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUserAvatar($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUserBirthday($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUserCity($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUserGithub($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUserId($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUserJob($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUserMainPage($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUserNickname($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserProfile whereUserSex($value)
* @mixin \Eloquent
*/
class UserProfile extends Model class UserProfile extends Model
{ {
use HasFactory; use HasFactory;
......
...@@ -10,16 +10,17 @@ ...@@ -10,16 +10,17 @@
"require": { "require": {
"php": "^7.3|^8.0", "php": "^7.3|^8.0",
"ext-json": "*", "ext-json": "*",
"doctrine/dbal": "^3.1",
"fruitcake/laravel-cors": "^2.0", "fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1", "guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^8.54", "laravel/framework": "^8.54",
"laravel/sanctum": "^2.11",
"laravel/tinker": "^2.5", "laravel/tinker": "^2.5",
"mews/captcha": "^3.2", "mews/captcha": "^3.2",
"predis/predis": "^1.1", "predis/predis": "^1.1",
"webpatser/laravel-uuid": "^4.0" "webpatser/laravel-uuid": "^4.0"
}, },
"require-dev": { "require-dev": {
"barryvdh/laravel-ide-helper": "^2.10",
"facade/ignition": "^2.5", "facade/ignition": "^2.5",
"fakerphp/faker": "^1.9.1", "fakerphp/faker": "^1.9.1",
"laravel/sail": "^1.0.1", "laravel/sail": "^1.0.1",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -14,9 +14,9 @@ class ApiUrl ...@@ -14,9 +14,9 @@ class ApiUrl
{ {
const API = '/api'; const API = '/api';
const USER = '/user'; const USER = '/user';
const CAPTCHA='/captcha'; const CAPTCHA = '/captcha';
const REGISTER = "/register"; const REGISTER = "/register";
const LOGIN = '/login';
} }
class Middleware class Middleware
...@@ -24,15 +24,48 @@ class Middleware ...@@ -24,15 +24,48 @@ class Middleware
const AUTH_MIDDLEWARE = 'AuthMiddleWare'; const AUTH_MIDDLEWARE = 'AuthMiddleWare';
} }
class UserTypeEnum{ class UserTypeEnum
const ADMIN="01"; {
const NORMAL="02"; const ADMIN = "01";
const VIP="03"; const NORMAL = "02";
const VIP = "03";
}
class UserStatusEnum
{
const NOT_VERITY = "01";
const NORMAL = "02";
const BANNED = "03";
const BANNED_FOREVER = "04";
} }
class UserStatusEnum{ class RedisCacheKey
const NOT_VERITY="01"; {
const NORMAL="02"; const SITE_PROFILE = "site_profile:";
const BANNED="03"; const USER_TOKEN = "user_token:";
const BANNED_FOREVER="04"; }
class CookieKey
{
const USER_TOKEN = "user_token";
}
class HeaderKey
{
const LOGIN_STATUS = "login_status";
const USER_INFO="user_info";
}
class SiteProfileTypeEnum
{
const WEB_TITLE = "01";
const SITE_URL = "02";
const WEB_FOOTER = "03";
}
class DefaultSiteProfile
{
const WEB_TITLE = 'Utopia 开放平台';
const SITE_URL = 'http://localhost';
const WEB_FOOTER='Copyright ©2021 <a href="https://www.utopiaxc.cn/">UtopiaXC</a> All Rights Reserved. | Powered By <a href="https://github.com/UtopiaXC/Utopia-Open-Platform" target="_blank">Utopia Open Platform</a>';
} }
<?php
class HTTP_CODE {
//成功请求 2xx
/**
* @var int 服务器成功响应
*/
const SUCCESS = 200;
//重定向 3xx
//客户端错误 4xx
/**
* @var int 错误的请求
*/
const BAD_REQUEST = 400;
/**
* @var int 请求由于SQL注入被拒绝
*/
const NOT_ACCEPT_SQL = 400001;
/**
* @var int 请求由于参数过长被拒绝
*/
const NOT_ACCEPT_PARAMS_TOO_LONG = 400002;
/**
* @var int 请求由于参数类型错误被拒绝
*/
const NOT_ACCEPT_PARAMS_TYPE_WRONG = 400003;
/**
* @var int 请求由于参数内容错误被拒绝
*/
const NOT_ACCEPT_PARAMS_CONTENT_WRONG = 400004;
/**
* @var int 请求由于请求语法错误被拒绝
*/
const NOT_ACCEPT_SYNTAX_WRONG = 400005;
/**
* @var int 请求参数存在不能为空的值
*/
const NOT_ACCEPT_NOT_BLANK = 400006;
/**
* @var int 验证失败
*/
const UNAUTHORIZED = 401;
/**
* @var int 验证码验证失败
*/
const UNAUTHORIZED_CAPTCHA = 401001;
/**
* @var int 请求被拒绝
*/
const REFUSED = 403;
/**
* @var int 注册信息不被服务器所接受
*/
const REFUSED_REGISTER_NOT_ACCEPT = 403001;
/**
* @var int 用户名或邮箱已存在
*/
const REFUSED_REGISTER_EXISTS = 403002;
/**
* @var int 用户不存在
*/
const REFUSED_LOGIN_NO_REGISTER=403003;
/**
* @var int 用户名或密码错误
*/
const REFUSED_LOGIN_WRONG=403004;
/**
* @var int 登录请求被拒绝,您的账号可能被封禁或停用
*/
const REFUSED_LOGIN_REFUSED=403005;
//服务器错误 5xx
/**
* @var int 服务器内部错误
*/
const INTERNAL_SERVER_ERROR = 500;
/**
* @var int 错误的网关
*/
const BAD_GATEWAY = 502;
}
...@@ -69,7 +69,7 @@ return [ ...@@ -69,7 +69,7 @@ return [
| |
*/ */
'timezone' => 'UTC', 'timezone' => 'PRC',
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
...@@ -82,7 +82,7 @@ return [ ...@@ -82,7 +82,7 @@ return [
| |
*/ */
'locale' => 'cn', 'locale' => 'zh_CN',
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
...@@ -95,7 +95,7 @@ return [ ...@@ -95,7 +95,7 @@ return [
| |
*/ */
'fallback_locale' => 'cn', 'fallback_locale' => 'en',
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
...@@ -141,7 +141,6 @@ return [ ...@@ -141,7 +141,6 @@ return [
/* /*
* Laravel Framework Service Providers... * Laravel Framework Service Providers...
*/ */
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class, Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class,
...@@ -158,7 +157,6 @@ return [ ...@@ -158,7 +157,6 @@ return [
Illuminate\Pipeline\PipelineServiceProvider::class, Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class, Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class, Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class,
...@@ -172,7 +170,6 @@ return [ ...@@ -172,7 +170,6 @@ return [
* Application Service Providers... * Application Service Providers...
*/ */
App\Providers\AppServiceProvider::class, App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class, // App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class, App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class, App\Providers\RouteServiceProvider::class,
...@@ -195,7 +192,6 @@ return [ ...@@ -195,7 +192,6 @@ return [
'App' => Illuminate\Support\Facades\App::class, 'App' => Illuminate\Support\Facades\App::class,
'Arr' => Illuminate\Support\Arr::class, 'Arr' => Illuminate\Support\Arr::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class, 'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class, 'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class, 'Bus' => Illuminate\Support\Facades\Bus::class,
......
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];
...@@ -54,7 +54,7 @@ return [ ...@@ -54,7 +54,7 @@ return [
'unix_socket' => env('DB_SOCKET', ''), 'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4', 'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci', 'collation' => 'utf8mb4_unicode_ci',
'prefix' => '', 'prefix' => env("APP_NAME") . "_",
'prefix_indexes' => true, 'prefix_indexes' => true,
'strict' => true, 'strict' => true,
'engine' => null, 'engine' => null,
...@@ -123,7 +123,7 @@ return [ ...@@ -123,7 +123,7 @@ return [
'options' => [ 'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'), 'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
], ],
'default' => [ 'default' => [
......
<?php
return [
/*
|--------------------------------------------------------------------------
| Filename & Format
|--------------------------------------------------------------------------
|
| The default filename
|
*/
'filename' => '_ide_helper.php',
/*
|--------------------------------------------------------------------------
| Where to write the PhpStorm specific meta file
|--------------------------------------------------------------------------
|
| PhpStorm also supports the directory `.phpstorm.meta.php/` with arbitrary
| files in it, should you need additional files for your project; e.g.
| `.phpstorm.meta.php/laravel_ide_Helper.php'.
|
*/
'meta_filename' => '.phpstorm.meta.php',
/*
|--------------------------------------------------------------------------
| Fluent helpers
|--------------------------------------------------------------------------
|
| Set to true to generate commonly used Fluent methods
|
*/
'include_fluent' => true,
/*
|--------------------------------------------------------------------------
| Factory Builders
|--------------------------------------------------------------------------
|
| Set to true to generate factory generators for better factory()
| method auto-completion.
|
| Deprecated for Laravel 8 or latest.
|
*/
'include_factory_builders' => false,
/*
|--------------------------------------------------------------------------
| Write Model Magic methods
|--------------------------------------------------------------------------
|
| Set to false to disable write magic methods of model
|
*/
'write_model_magic_where' => true,
/*
|--------------------------------------------------------------------------
| Write Model External Eloquent Builder methods
|--------------------------------------------------------------------------
|
| Set to false to disable write external eloquent builder methods
|
*/
'write_model_external_builder_methods' => true,
/*
|--------------------------------------------------------------------------
| Write Model relation count properties
|--------------------------------------------------------------------------
|
| Set to false to disable writing of relation count properties to model DocBlocks.
|
*/
'write_model_relation_count_properties' => true,
/*
|--------------------------------------------------------------------------
| Write Eloquent Model Mixins
|--------------------------------------------------------------------------
|
| This will add the necessary DocBlock mixins to the model class
| contained in the Laravel Framework. This helps the IDE with
| auto-completion.
|
| Please be aware that this setting changes a file within the /vendor directory.
|
*/
'write_eloquent_model_mixins' => false,
/*
|--------------------------------------------------------------------------
| Helper files to include
|--------------------------------------------------------------------------
|
| Include helper files. By default not included, but can be toggled with the
| -- helpers (-H) option. Extra helper files can be included.
|
*/
'include_helpers' => false,
'helper_files' => [
base_path() . '/vendor/laravel/framework/src/Illuminate/Support/helpers.php',
],
/*
|--------------------------------------------------------------------------
| Model locations to include
|--------------------------------------------------------------------------
|
| Define in which directories the ide-helper:models command should look
| for models.
|
| glob patterns are supported to easier reach models in sub-directories,
| e.g. `app/Services/* /Models` (without the space)
|
*/
'model_locations' => [
'app',
],
/*
|--------------------------------------------------------------------------
| Models to ignore
|--------------------------------------------------------------------------
|
| Define which models should be ignored.
|
*/
'ignored_models' => [
],
/*
|--------------------------------------------------------------------------
| Models hooks
|--------------------------------------------------------------------------
|
| Define which hook classes you want to run for models to add custom information
|
| Hooks should implement Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface.
|
*/
'model_hooks' => [
// App\Support\IdeHelper\MyModelHook::class
],
/*
|--------------------------------------------------------------------------
| Extra classes
|--------------------------------------------------------------------------
|
| These implementations are not really extended, but called with magic functions
|
*/
'extra' => [
'Eloquent' => ['Illuminate\Database\Eloquent\Builder', 'Illuminate\Database\Query\Builder'],
'Session' => ['Illuminate\Session\Store'],
'Redis' => [\Illuminate\Redis\Connections\PhpRedisConnection::class],
'Uuid'=>[\Webpatser\Uuid\Uuid::class],
],
'magic' => [],
/*
|--------------------------------------------------------------------------
| Interface implementations
|--------------------------------------------------------------------------
|
| These interfaces will be replaced with the implementing class. Some interfaces
| are detected by the helpers, others can be listed below.
|
*/
'interfaces' => [
],
/*
|--------------------------------------------------------------------------
| Support for custom DB types
|--------------------------------------------------------------------------
|
| This setting allow you to map any custom database type (that you may have
| created using CREATE TYPE statement or imported using database plugin
| / extension to a Doctrine type.
|
| Each key in this array is a name of the Doctrine2 DBAL Platform. Currently valid names are:
| 'postgresql', 'db2', 'drizzle', 'mysql', 'oracle', 'sqlanywhere', 'sqlite', 'mssql'
|
| This name is returned by getName() method of the specific Doctrine/DBAL/Platforms/AbstractPlatform descendant
|
| The value of the array is an array of type mappings. Key is the name of the custom type,
| (for example, "jsonb" from Postgres 9.4) and the value is the name of the corresponding Doctrine2 type (in
| our case it is 'json_array'. Doctrine types are listed here:
| http://doctrine-dbal.readthedocs.org/en/latest/reference/types.html
|
| So to support jsonb in your models when working with Postgres, just add the following entry to the array below:
|
| "postgresql" => array(
| "jsonb" => "json_array",
| ),
|
*/
'custom_db_types' => [
],
/*
|--------------------------------------------------------------------------
| Support for camel cased models
|--------------------------------------------------------------------------
|
| There are some Laravel packages (such as Eloquence) that allow for accessing
| Eloquent model properties via camel case, instead of snake case.
|
| Enabling this option will support these packages by saving all model
| properties as camel case, instead of snake case.
|
| For example, normally you would see this:
|
| * @property \Illuminate\Support\Carbon $created_at
| * @property \Illuminate\Support\Carbon $updated_at
|
| With this enabled, the properties will be this:
|
| * @property \Illuminate\Support\Carbon $createdAt
| * @property \Illuminate\Support\Carbon $updatedAt
|
| Note, it is currently an all-or-nothing option.
|
*/
'model_camel_case_properties' => false,
/*
|--------------------------------------------------------------------------
| Property Casts
|--------------------------------------------------------------------------
|
| Cast the given "real type" to the given "type".
|
*/
'type_overrides' => [
'integer' => 'int',
'boolean' => 'bool',
],
/*
|--------------------------------------------------------------------------
| Include DocBlocks from classes
|--------------------------------------------------------------------------
|
| Include DocBlocks from classes to allow additional code inspection for
| magic methods and properties.
|
*/
'include_class_docblocks' => false,
/*
|--------------------------------------------------------------------------
| Force FQN usage
|--------------------------------------------------------------------------
|
| Use the fully qualified (class) name in docBlock,
| event if class exists in a given file
| or there is an import (use className) of a given class
|
*/
'force_fqn' => false,
/*
|--------------------------------------------------------------------------
| Additional relation types
|--------------------------------------------------------------------------
|
| Sometimes it's needed to create custom relation types. The key of the array
| is the Relationship Method name. The value of the array is the canonical class
| name of the Relationship, e.g. `'relationName' => RelationShipClass::class`.
|
*/
'additional_relation_types' => [],
/*
|--------------------------------------------------------------------------
| Run artisan commands after migrations to generate model helpers
|--------------------------------------------------------------------------
|
| The specified commands should run after migrations are finished running.
|
*/
'post_migrate' => [
// 'ide-helper:models --nowrite',
],
];
...@@ -26,6 +26,7 @@ class CreateUsersProfile extends Migration ...@@ -26,6 +26,7 @@ class CreateUsersProfile extends Migration
$table->string('user_github')->nullable();; $table->string('user_github')->nullable();;
$table->timestamps(); $table->timestamps();
}); });
} }
/** /**
......
...@@ -14,14 +14,16 @@ class CreateUsersTable extends Migration ...@@ -14,14 +14,16 @@ class CreateUsersTable extends Migration
public function up() public function up()
{ {
Schema::create('users', function (Blueprint $table) { Schema::create('users', function (Blueprint $table) {
$table->uuid('id'); $table->uuid('id')->unique();
$table->string('user_name'); $table->string('user_name')->unique();
$table->string('user_email'); $table->string('user_email')->unique();
$table->string('user_password'); $table->string('user_password');
$table->string('user_type'); $table->string('user_type');
$table->string('user_status'); $table->string('user_status');
$table->timestamps(); $table->timestamps();
}); });
} }
/** /**
......
...@@ -15,7 +15,7 @@ class CreateSiteProfile extends Migration ...@@ -15,7 +15,7 @@ class CreateSiteProfile extends Migration
{ {
Schema::create('site_profile', function (Blueprint $table) { Schema::create('site_profile', function (Blueprint $table) {
$table->uuid('id'); $table->uuid('id');
$table->string('profile_type'); $table->string('profile_type')->unique();
$table->string('profile_description'); $table->string('profile_description');
$table->string('profile_content'); $table->string('profile_content');
$table->timestamps(); $table->timestamps();
......
<?php
namespace Database\Seeders;
use App\Models\Users\User;
use App\Models\Users\UserProfile;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use UserStatusEnum;
use UserTypeEnum;
use Webpatser\Uuid\Uuid;
class AddAdminUserSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
* @throws \Throwable
*/
public function run()
{
DB::beginTransaction();
try {
//以下添加默认管理员账户
$user = new User();
$user->id = Uuid::generate();
$user->user_name = "admin";
$user->user_email = "admin@admin.com";
//默认密码Admin12345678
$user->user_password = '$2y$10$lb4WYqFMVtR7vlZMnTi7jO0ROBXzkSRGDK0vrnk965RfQAIsgSpO.';
$user->user_type = UserTypeEnum::ADMIN;
$user->user_status = UserStatusEnum::NORMAL;
$user->save();
$user_profile = new UserProfile();
$user_profile->id = Uuid::generate();
$user_profile->user_id = $user->id;
$user_profile->save();
}catch (\Exception $e){
DB::rollBack();
}
DB::commit();
}
}
...@@ -13,6 +13,9 @@ class DatabaseSeeder extends Seeder ...@@ -13,6 +13,9 @@ class DatabaseSeeder extends Seeder
*/ */
public function run() public function run()
{ {
// \App\Models\User::factory(10)->create(); $this->call([
AddAdminUserSeeder::class,
SiteProfileSeeder::class,
]);
} }
} }
<?php
namespace Database\Seeders;
use App\Models\System\SiteProfile;
use DB;
use Illuminate\Database\Seeder;
class SiteProfileSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
* @throws \Throwable
*/
public function run()
{
DB:: beginTransaction();
try {
//网站标题
$site_profile=new SiteProfile();
$site_profile->id=\Uuid::generate();
$site_profile->profile_type=\SiteProfileTypeEnum::WEB_TITLE;
$site_profile->profile_description=trans('site_profile_description.'.\SiteProfileTypeEnum::WEB_TITLE);
$site_profile->profile_content=\DefaultSiteProfile::WEB_TITLE;
$site_profile->save();
//网站地址
$site_profile=new SiteProfile();
$site_profile->id=\Uuid::generate();
$site_profile->profile_type=\SiteProfileTypeEnum::SITE_URL;
$site_profile->profile_description=trans('site_profile_description.'.\SiteProfileTypeEnum::SITE_URL);
$site_profile->profile_content=\DefaultSiteProfile::SITE_URL;
$site_profile->save();
//网站注脚
$site_profile=new SiteProfile();
$site_profile->id=\Uuid::generate();
$site_profile->profile_type=\SiteProfileTypeEnum::WEB_FOOTER;
$site_profile->profile_description=trans('site_profile_description.'.\SiteProfileTypeEnum::WEB_FOOTER);
$site_profile->profile_content=\DefaultSiteProfile::WEB_FOOTER;
$site_profile->save();
}catch (\Exception $e){
DB::rollBack();
}
DB::commit();
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'These credentials do not match our records.',
'password' => 'The provided password is incorrect.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Previous',
'next' => 'Next &raquo;',
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
'reset' => 'Your password has been reset!',
'sent' => 'We have emailed your password reset link!',
'throttled' => 'Please wait before retrying.',
'token' => 'This password reset token is invalid.',
'user' => "We can't find a user with that email address.",
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => 'The :attribute must be accepted.',
'accepted_if' => 'The :attribute must be accepted when :other is :value.',
'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.',
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
'alpha' => 'The :attribute must only contain letters.',
'alpha_dash' => 'The :attribute must only contain letters, numbers, dashes and underscores.',
'alpha_num' => 'The :attribute must only contain letters and numbers.',
'array' => 'The :attribute must be an array.',
'before' => 'The :attribute must be a date before :date.',
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
'between' => [
'numeric' => 'The :attribute must be between :min and :max.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'string' => 'The :attribute must be between :min and :max characters.',
'array' => 'The :attribute must have between :min and :max items.',
],
'boolean' => 'The :attribute field must be true or false.',
'confirmed' => 'The :attribute confirmation does not match.',
'current_password' => 'The password is incorrect.',
'date' => 'The :attribute is not a valid date.',
'date_equals' => 'The :attribute must be a date equal to :date.',
'date_format' => 'The :attribute does not match the format :format.',
'different' => 'The :attribute and :other must be different.',
'digits' => 'The :attribute must be :digits digits.',
'digits_between' => 'The :attribute must be between :min and :max digits.',
'dimensions' => 'The :attribute has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'email' => 'The :attribute must be a valid email address.',
'ends_with' => 'The :attribute must end with one of the following: :values.',
'exists' => 'The selected :attribute is invalid.',
'file' => 'The :attribute must be a file.',
'filled' => 'The :attribute field must have a value.',
'gt' => [
'numeric' => 'The :attribute must be greater than :value.',
'file' => 'The :attribute must be greater than :value kilobytes.',
'string' => 'The :attribute must be greater than :value characters.',
'array' => 'The :attribute must have more than :value items.',
],
'gte' => [
'numeric' => 'The :attribute must be greater than or equal :value.',
'file' => 'The :attribute must be greater than or equal :value kilobytes.',
'string' => 'The :attribute must be greater than or equal :value characters.',
'array' => 'The :attribute must have :value items or more.',
],
'image' => 'The :attribute must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field does not exist in :other.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'ipv4' => 'The :attribute must be a valid IPv4 address.',
'ipv6' => 'The :attribute must be a valid IPv6 address.',
'json' => 'The :attribute must be a valid JSON string.',
'lt' => [
'numeric' => 'The :attribute must be less than :value.',
'file' => 'The :attribute must be less than :value kilobytes.',
'string' => 'The :attribute must be less than :value characters.',
'array' => 'The :attribute must have less than :value items.',
],
'lte' => [
'numeric' => 'The :attribute must be less than or equal :value.',
'file' => 'The :attribute must be less than or equal :value kilobytes.',
'string' => 'The :attribute must be less than or equal :value characters.',
'array' => 'The :attribute must not have more than :value items.',
],
'max' => [
'numeric' => 'The :attribute must not be greater than :max.',
'file' => 'The :attribute must not be greater than :max kilobytes.',
'string' => 'The :attribute must not be greater than :max characters.',
'array' => 'The :attribute must not have more than :max items.',
],
'mimes' => 'The :attribute must be a file of type: :values.',
'mimetypes' => 'The :attribute must be a file of type: :values.',
'min' => [
'numeric' => 'The :attribute must be at least :min.',
'file' => 'The :attribute must be at least :min kilobytes.',
'string' => 'The :attribute must be at least :min characters.',
'array' => 'The :attribute must have at least :min items.',
],
'multiple_of' => 'The :attribute must be a multiple of :value.',
'not_in' => 'The selected :attribute is invalid.',
'not_regex' => 'The :attribute format is invalid.',
'numeric' => 'The :attribute must be a number.',
'password' => 'The password is incorrect.',
'present' => 'The :attribute field must be present.',
'regex' => 'The :attribute format is invalid.',
'required' => 'The :attribute field is required.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values are present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'required_without_all' => 'The :attribute field is required when none of :values are present.',
'prohibited' => 'The :attribute field is prohibited.',
'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
'same' => 'The :attribute and :other must match.',
'size' => [
'numeric' => 'The :attribute must be :size.',
'file' => 'The :attribute must be :size kilobytes.',
'string' => 'The :attribute must be :size characters.',
'array' => 'The :attribute must contain :size items.',
],
'starts_with' => 'The :attribute must start with one of the following: :values.',
'string' => 'The :attribute must be a string.',
'timezone' => 'The :attribute must be a valid timezone.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'url' => 'The :attribute must be a valid URL.',
'uuid' => 'The :attribute must be a valid UUID.',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap our attribute placeholder
| with something more reader friendly such as "E-Mail Address" instead
| of "email". This simply helps us make our message more expressive.
|
*/
'attributes' => [],
];
<?php
return ["code" => [
//2xx
HTTP_CODE::SUCCESS => "成功",
//3xx
//4xx
//400xxx
HTTP_CODE::BAD_REQUEST => "错误的请求",
HTTP_CODE::NOT_ACCEPT_SQL => '请求由于SQL注入被拒绝',
HTTP_CODE::NOT_ACCEPT_PARAMS_TOO_LONG => '请求由于参数过长被拒绝',
HTTP_CODE::NOT_ACCEPT_PARAMS_TYPE_WRONG => '请求由于参数类型错误被拒绝',
HTTP_CODE::NOT_ACCEPT_PARAMS_CONTENT_WRONG => '请求由于参数内容错误被拒绝',
HTTP_CODE::NOT_ACCEPT_SYNTAX_WRONG => '请求由于请求语法错误被拒绝',
HTTP_CODE::NOT_ACCEPT_NOT_BLANK=>'参数不能存在空值',
//401xxx
HTTP_CODE::UNAUTHORIZED => "未认证",
HTTP_CODE::UNAUTHORIZED_CAPTCHA => "验证码错误或超时",
//403xxx
HTTP_CODE::REFUSED => '请求被拒绝',
HTTP_CODE::REFUSED_REGISTER_NOT_ACCEPT => '注册信息不被服务器所接受',
HTTP_CODE::REFUSED_REGISTER_EXISTS => '用户名或邮箱已存在',
HTTP_CODE::REFUSED_LOGIN_NO_REGISTER => '用户不存在',
HTTP_CODE::REFUSED_LOGIN_WRONG => '用户名或密码错误',
HTTP_CODE::REFUSED_LOGIN_REFUSED => '登录请求被拒绝,您的账号可能被封禁或停用',
//5xx
HTTP_CODE::INTERNAL_SERVER_ERROR => '服务器内部错误',
HTTP_CODE::BAD_GATEWAY => '错误的网关',
]
];
<?php
return [
SiteProfileTypeEnum::WEB_TITLE => '网站标题',
SiteProfileTypeEnum::SITE_URL => '网站URL',
SiteProfileTypeEnum::WEB_FOOTER=>'网站版权注脚信息',
];
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
@section('title') - 登录 @endsection @section('title') - 登录 @endsection
@section('body') @section('body')
<body class="login-page"> <body class="login-page">
<div class='loader'> <div class='loader'>
<div class='spinner-grow text-primary' role='status'><span class='sr-only'>Loading...</span></div> <div class='spinner-grow text-primary' role='status'><span class='sr-only'>Loading...</span></div>
</div> </div>
<div class="container"> <div class="container">
<div class="row justify-content-md-center"> <div class="row justify-content-md-center">
<div class="col-md-12 col-lg-4"> <div class="col-md-12 col-lg-4">
<div class="card login-box-container"> <div class="card login-box-container">
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
<form> <form>
<div class="mb-3"> <div class="mb-3">
<div class="form-floating"> <div class="form-floating">
<input type="text" class="form-control" id="email" <input type="text" class="form-control" id="user"
placeholder="邮箱或用户名"> placeholder="邮箱或用户名">
<label for="email">邮箱或用户名</label> <label for="user">邮箱或用户名</label>
</div> </div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
...@@ -30,9 +30,15 @@ ...@@ -30,9 +30,15 @@
<label for="password">密码</label> <label for="password">密码</label>
</div> </div>
</div> </div>
<div class="d-grid"> <div class="d-grid">
<button type="button" onclick="doLogin()" class="btn btn-info m-b-xs">登录</button> <div id="login_process" style="display: none;" class="progress m-b-xs">
<button type="button" class="btn btn-primary" onclick="window.location.href='{{WebUrl::FIND_PASSWORD}}'"> <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
</div>
<button id="login_button" type="button" onclick="doLogin()" class="btn btn-info m-b-xs">登录</button>
<button type="button" class="btn btn-primary"
onclick="window.location.href='{{WebUrl::FIND_PASSWORD}}'">
找回密码 找回密码
</button> </button>
</div> </div>
...@@ -44,8 +50,8 @@ ...@@ -44,8 +50,8 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="modal fade" id="alert" tabindex="-1" aria-labelledby="alert" aria-hidden="true"> <div class="modal fade" id="alert" tabindex="-1" aria-labelledby="alert" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
...@@ -58,29 +64,116 @@ ...@@ -58,29 +64,116 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</body> <div class="modal fade" id="captcha_dialog" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false"
aria-labelledby="captcha" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="captcha_title">CAPTCHA 验证码</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="captcha_content">
<div id="captcha_process" class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
</div>
<div class="input-group mb-3" id="captcha_div" style="display: none">
<span class="input-group-text"><img id="captcha_img" style="display: none;" src=""
alt="captcha"></span>
<label for="captcha"></label>
<input type="text" class="form-control" id="captcha" aria-describedby="basic-addon3"
placeholder="验证码">
</div>
<div class="modal-footer" style="display: flex;justify-content: flex-end">
<button type="button" onclick="$('#login_process').hide();$('#login_button').show()" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" onclick="doCaptcha();" class="btn btn-primary">验证</button>
</div>
</div>
</div>
</div>
</div>
</body>
@endsection @endsection
@section('script') @section('script')
<script> <script src="https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.18.0/js/md5.js"></script>
function doLogin(){ <script>
let email=$("#email").val() function doLogin() {
let password=$("#password").val() let user = $("#user").val()
if (email===""||password===""){ let password = $("#password").val()
showAlert("警告","您有未输入的部分") if (user === "" || password === "") {
return showAlert("警告", "您有未输入的部分")
}
let pattern = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
if (!pattern.test(email)) {
showAlert("警告", "邮箱格式错误")
return return
} }
$.ajax({
$("#captcha_dialog").modal('show')
$("#login_process").show()
$("#login_button").hide()
$.ajax({
url: '{{ApiUrl::API.ApiUrl::CAPTCHA}}',
method: "get",
dataType: "json",
success: function (result) {
if (result.code === 200) {
$("#captcha_process").hide()
let captcha_img = $("#captcha_img")
captcha_img.attr("src", result.data.captcha_img)
captcha_img.show()
$("#captcha_div").show()
} else {
$("#login_process").hide()
$("#login_button").show()
showAlert("抱歉", "服务器错误,未获取到验证码")
}
},
error: function () {
$("#login_process").hide()
$("#login_button").show()
showAlert("抱歉", "服务器错误,未获取到验证码")
}
}) })
}
function doCaptcha(){
let process = $("#captcha_process")
process.show()
$("#captcha_div").hide()
let user = $("#user").val()
let password = $("#password").val()
let captcha = $("#captcha").val()
$.ajax({
url: '{{ApiUrl::API.ApiUrl::USER.ApiUrl::LOGIN}}',
dataType: "json",
type:'post',
data: {
"user": user,
"password": md5(password),
"captcha":captcha
},
success: function (result) {
$("#captcha_dialog").modal('hide')
$("#login_process").hide()
$("#login_button").show()
if(result.code===200){
window.location.href="/";
}else{
showAlert("抱歉",result.message)
} }
},
error: function () {
$("#login_process").hide()
$("#login_button").show()
$("#captcha_dialog").modal('hide')
showAlert("抱歉","服务器错误")
}
})
}
function showAlert(title, content) { function showAlert(title, content) {
let alert = $("#alert") let alert = $("#alert")
let title_elem = $("#alert_title") let title_elem = $("#alert_title")
...@@ -89,5 +182,5 @@ ...@@ -89,5 +182,5 @@
content_elem.html(content) content_elem.html(content)
alert.modal('show') alert.modal('show')
} }
</script> </script>
@endsection @endsection
...@@ -199,7 +199,7 @@ ...@@ -199,7 +199,7 @@
data: { data: {
"email": email, "email": email,
"user_name": user_name, "user_name": user_name,
"passeord": password, "password": password,
"captcha": captcha "captcha": captcha
}, },
success: function (result) { success: function (result) {
......
...@@ -16,5 +16,6 @@ use Illuminate\Support\Facades\Route; ...@@ -16,5 +16,6 @@ use Illuminate\Support\Facades\Route;
| |
*/ */
Route::post(ApiUrl::USER.ApiUrl::REGISTER, [UserController::class,"register"]);
Route::get(ApiUrl::CAPTCHA,[CaptchaController::class,"getCaptcha"]); Route::get(ApiUrl::CAPTCHA,[CaptchaController::class,"getCaptcha"]);
Route::post(ApiUrl::USER.ApiUrl::REGISTER, [UserController::class,"register"]);
Route::post(ApiUrl::USER.ApiUrl::LOGIN,[UserController::class,"login"]);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment