This commit is contained in:
筱锋xiao_lfeng 2023-06-11 14:20:56 +08:00
parent d75b229ba0
commit 364015f906
42 changed files with 59439 additions and 106 deletions

18
.editorconfig Normal file
View File

@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4

View File

@ -15,7 +15,7 @@ class Kernel extends ConsoleKernel
/**
* Define the application's command schedule.
*
* @param Schedule $schedule
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
@ -30,7 +30,7 @@ protected function schedule(Schedule $schedule)
*/
protected function commands()
{
$this->load(__DIR__ . '/Commands');
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}

View File

@ -0,0 +1,70 @@
<?php
/*
* Copyright © 2016 - 2023 筱锋xiao_lfeng. All Rights Reserved.
* 开发开源遵循 MIT 许可,若需商用请联系开发者
* https://www.x-lf.com/
*/
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Response;
class Authme extends Authenticatable
{
public function Register(Request $request): JsonResponse
{
$request->validate([
'username' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:6|confirmed',
]);
$user = new User();
$user->username = $request->username;
$user->email = $request->email;
$user->password = bcrypt($request->password);
$user->save();
auth()->login($user);
$jsonData = [
'output' => 'Success',
'code' => 200,
'data' => [
'message' => '登陆成功',
],
];
return Response::json($jsonData);
}
public function Login(Request $request): JsonResponse
{
// 获取参数
$loginData = $request->only('email','password');
if (Auth::attempt($loginData,true)) {
// 登录成功
$jsonData = [
'output' => 'Success',
'code' => 200,
'data' => [
'message' => '登陆成功',
],
];
} else {
// 登陆失败
$jsonData = [
'output' => 'LoginFail',
'code' => 403,
'data' => [
'message' => '登陆失败',
],
];
}
return Response::json($jsonData);
}
}

View File

@ -9,24 +9,20 @@
use App\Http\Middleware\Authenticate;
use App\Http\Middleware\EncryptCookies;
use App\Http\Middleware\PreventRequestsDuringMaintenance;
use App\Http\Middleware\RedirectIfAuthenticated;
use App\Http\Middleware\TrimStrings;
use App\Http\Middleware\TrustProxies;
use App\Http\Middleware\VerifyCsrfToken;
use Fruitcake\Cors\HandleCors;
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
use Illuminate\Auth\Middleware\Authorize;
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
use Illuminate\Auth\Middleware\RequirePassword;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
use Illuminate\Http\Middleware\SetCacheHeaders;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Routing\Middleware\ValidateSignature;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
@ -40,15 +36,15 @@ class Kernel extends HttpKernel
* @var array<int, class-string|string>
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
TrustProxies::class,
HandleCors::class,
PreventRequestsDuringMaintenance::class,
ValidatePostSize::class,
TrimStrings::class,
ConvertEmptyStringsToNull::class,
CheckForMaintenanceMode::class,
StartSession::class,
\Illuminate\Cookie\Middleware\EncryptCookies::class,
AddQueuedCookiesToResponse::class,
AuthenticateSession::class,
// 其他中间件
];
/**
* The application's route middleware groups.
*
@ -59,7 +55,7 @@ class Kernel extends HttpKernel
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,

View File

@ -8,19 +8,18 @@
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param Request $request
* @param \Illuminate\Http\Request $request
* @return string|null
*/
protected function redirectTo($request)
{
if (!$request->expectsJson()) {
if (! $request->expectsJson()) {
return route('login');
}
}

View File

@ -9,9 +9,7 @@
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
@ -19,10 +17,10 @@ class RedirectIfAuthenticated
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure(Request): (Response|RedirectResponse) $next
* @param string|null ...$guards
* @return Response|RedirectResponse
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @param string|null ...$guards
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next, ...$guards)
{

View File

@ -7,6 +7,7 @@
namespace App\Providers;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
@ -28,6 +29,6 @@ public function register()
*/
public function boot()
{
//
Schema::defaultStringLength(191);
}
}

View File

@ -44,7 +44,7 @@
|
*/
'debug' => (bool)env('APP_DEBUG', false),
'debug' => (bool) env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------

View File

@ -128,7 +128,7 @@
'options' => [
'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' => [

View File

@ -43,7 +43,7 @@
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL') . '/storage',
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],

View File

@ -21,7 +21,7 @@
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : ''
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
/*

View File

@ -133,7 +133,7 @@
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_') . '_session'
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
/*

View File

@ -31,7 +31,7 @@ public function definition()
/**
* Indicate that the model's email address should be unverified.
*
* @return Factory
* @return \Illuminate\Database\Eloquent\Factories\Factory
*/
public function unverified()
{

View File

@ -1,41 +0,0 @@
<?php
/*
* Copyright © 2016 - 2023 筱锋xiao_lfeng. All Rights Reserved.
* 开发开源遵循 MIT 许可,若需商用请联系开发者
* https://www.x-lf.com/
*/
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePersonalAccessTokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->id();
$table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('personal_access_tokens');
}
}

View File

@ -20,11 +20,9 @@ public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->string('username',40);
$table->string('email',100)->unique();
$table->string('password',255);
$table->timestamps();
});
}
@ -36,6 +34,6 @@ public function up()
*/
public function down()
{
Schema::dropIfExists('users');
//
}
}

View File

@ -9,7 +9,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePasswordResetsTable extends Migration
class UpdateUsersTable extends Migration
{
/**
* Run the migrations.
@ -18,10 +18,8 @@ class CreatePasswordResetsTable extends Migration
*/
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
Schema::table('users', function (Blueprint $table) {
$table->rememberToken();
});
}
@ -32,6 +30,8 @@ public function up()
*/
public function down()
{
Schema::dropIfExists('password_resets');
Schema::table('users', function (Blueprint $table) {
//
});
}
}

View File

@ -9,7 +9,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateFailedJobsTable extends Migration
class CreateSessionsTable extends Migration
{
/**
* Run the migrations.
@ -18,14 +18,13 @@ class CreateFailedJobsTable extends Migration
*/
public function up()
{
Schema::create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->string('uuid')->unique();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
Schema::create('sessions', function (Blueprint $table) {
$table->string('id')->primary();
$table->foreignId('user_id')->nullable()->index();
$table->string('ip_address', 45)->nullable();
$table->text('user_agent')->nullable();
$table->text('payload');
$table->integer('last_activity')->index();
});
}
@ -36,6 +35,6 @@ public function up()
*/
public function down()
{
Schema::dropIfExists('failed_jobs');
Schema::dropIfExists('sessions');
}
}

9327
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

24
package.json Normal file
View File

@ -0,0 +1,24 @@
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"autoprefixer": "^10.4.14",
"axios": "^0.21",
"flowbite": "^1.6.5",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"postcss": "^8.4.24",
"tailwindcss": "^3.3.2"
},
"dependencies": {
"@tailwindcss/forms": "^0.5.3"
}
}

12
postcss.config.js Normal file
View File

@ -0,0 +1,12 @@
/*
* Copyright © 2016 - 2023 筱锋xiao_lfeng. All Rights Reserved.
* 开发开源遵循 MIT 许可若需商用请联系开发者
* https://www.x-lf.com/
*/
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

2113
public/css/app.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@
|
*/
if (file_exists($maintenance = __DIR__ . '/../storage/framework/maintenance.php')) {
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
require $maintenance;
}
@ -36,7 +36,7 @@
|
*/
require __DIR__ . '/../vendor/autoload.php';
require __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
@ -49,7 +49,7 @@
|
*/
$app = require_once __DIR__ . '/../bootstrap/app.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Kernel::class);

25367
public/js/app.js Normal file

File diff suppressed because it is too large Load Diff

10985
public/js/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

8
public/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

7
public/js/jquery.min.map Normal file

File diff suppressed because one or more lines are too long

4
public/mix-manifest.json Normal file
View File

@ -0,0 +1,4 @@
{
"/js/app.js": "/js/app.js",
"/css/app.css": "/css/app.css"
}

View File

@ -4,3 +4,6 @@
* https://www.x-lf.com/
*/
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -5,3 +5,4 @@
*/
require('./bootstrap');
import 'flowbite';

10985
resources/js/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<?php

View File

@ -0,0 +1,81 @@
<!doctype html>
<html lang="zh-CN" class="h-full bg-white">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
<title>Document</title>
</head>
<body class="h-full">
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600"
alt="Your Company">
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">登录您的账号</h2>
</div>
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
<form class="space-y-6" id="FormData" action="#" onsubmit="return false" method="POST">
@csrf
<div>
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">邮箱地址/用户名</label>
<div class="mt-2">
<input id="email" name="email" type="email" autocomplete="email" required
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div>
<div class="flex items-center justify-between">
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">密码</label>
<div class="text-sm">
<a href="{{ route('forgotpassword') }}"
class="font-semibold text-indigo-600 hover:text-indigo-500">忘记密码?</a>
</div>
</div>
<div class="mt-2">
<input id="password" name="password" type="password" autocomplete="current-password" required
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div>
<button type="submit"
class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
onclick="user_change()">
登录
</button>
</div>
</form>
<p class="mt-10 text-center text-sm text-gray-500">
还没有账号?
<a href="{{ route('register') }}"
class="font-semibold leading-6 text-indigo-600 hover:text-indigo-500">点击注册</a>
</p>
</div>
</div>
</body>
<script src="{{ asset('js/app.js') }}"></script>
<script src="{{ asset('js/jquery.js') }}"></script>
<script type="text/javascript">
function user_change() {
$.ajax({
async: true,
method: "POST",
data: $('#FormData').serialize(),
url: '{{ route('api.auth.login') }}',
dataType: "json",
success: function (returnData) {
if (returnData.output === "Success") {
window.location.href = '{{ route('console.dashboard') }}'
} else {
window.alert("错误!")
}
}
});
}
</script>
</html>

View File

@ -0,0 +1,96 @@
<!doctype html>
<html lang="zh-CN" class="h-full bg-white">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
<title>Document</title>
</head>
<body class="h-full">
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600"
alt="Your Company">
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">注册您的账号</h2>
</div>
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
<form class="space-y-6" id="FormData" action="#" onsubmit="return false" method="POST">
@csrf
<div>
<label for="username" class="block text-sm font-medium leading-6 text-gray-900">用户名</label>
<div class="mt-2">
<input id="username" name="username" type="text" autocomplete="username" required
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div>
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">邮箱地址</label>
<div class="mt-2">
<input id="email" name="email" type="email" autocomplete="email" required
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div>
<div class="flex items-center justify-between">
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">密码</label>
</div>
<div class="mt-2">
<input id="password" name="password" type="password" autocomplete="current-password" required
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div>
<div class="flex items-center justify-between">
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">重复密码</label>
</div>
<div class="mt-2">
<input id="password_confirmation" name="password_confirmation" type="password"
autocomplete="current-password" required
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
</div>
</div>
<div>
<button type="submit"
class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
onclick="user_change()">
注册
</button>
</div>
</form>
<p class="mt-10 text-center text-sm text-gray-500">
已经有账号了?
<a href="{{ route('login') }}" class="font-semibold leading-6 text-indigo-600 hover:text-indigo-500">
点击登录!</a>
</p>
</div>
</div>
</body>
<script src="{{ asset('js/app.js') }}"></script>
<script src="{{ asset('js/jquery.js') }}"></script>
<script type="text/javascript">
function user_change() {
$.ajax({
async: true,
method: "POST",
data: $('#FormData').serialize(),
url: '{{ route('api.auth.register') }}',
dataType: "json",
success: function (returnData) {
if (returnData.output === "Success") {
window.location.href = '{{ route('console.dashboard') }}'
} else {
window.alert("错误!")
}
}
});
}
</script>
</html>

View File

@ -0,0 +1,214 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
<title>Document</title>
</head>
<body>
<button data-drawer-target="sidebar-multi-level-sidebar" data-drawer-toggle="sidebar-multi-level-sidebar"
aria-controls="sidebar-multi-level-sidebar" type="button"
class="inline-flex items-center p-2 mt-2 ml-3 text-sm text-gray-500 rounded-lg sm:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600">
<span class="sr-only">Open sidebar</span>
<svg class="w-6 h-6" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path clip-rule="evenodd" fill-rule="evenodd"
d="M2 4.75A.75.75 0 012.75 4h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 4.75zm0 10.5a.75.75 0 01.75-.75h7.5a.75.75 0 010 1.5h-7.5a.75.75 0 01-.75-.75zM2 10a.75.75 0 01.75-.75h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 10z"></path>
</svg>
</button>
<aside id="sidebar-multi-level-sidebar"
class="fixed top-0 left-0 z-40 w-64 h-screen transition-transform -translate-x-full sm:translate-x-0"
aria-label="Sidebar">
<div class="h-full px-3 py-4 overflow-y-auto bg-gray-50 dark:bg-gray-800">
<ul class="space-y-2 font-medium">
<li>
<a href="#"
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<svg aria-hidden="true"
class="w-6 h-6 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"
fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="M2 10a8 8 0 018-8v8h8a8 8 0 11-16 0z"></path>
<path d="M12 2.252A8.014 8.014 0 0117.748 8H12V2.252z"></path>
</svg>
<span class="ml-3">Dashboard</span>
</a>
</li>
<li>
<button type="button"
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700"
aria-controls="dropdown-example" data-collapse-toggle="dropdown-example">
<svg aria-hidden="true"
class="flex-shrink-0 w-6 h-6 text-gray-500 transition duration-75 group-hover:text-gray-900 dark:text-gray-400 dark:group-hover:text-white"
fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M10 2a4 4 0 00-4 4v1H5a1 1 0 00-.994.89l-1 9A1 1 0 004 18h12a1 1 0 00.994-1.11l-1-9A1 1 0 0015 7h-1V6a4 4 0 00-4-4zm2 5V6a2 2 0 10-4 0v1h4zm-6 3a1 1 0 112 0 1 1 0 01-2 0zm7-1a1 1 0 100 2 1 1 0 000-2z"
clip-rule="evenodd"></path>
</svg>
<span class="flex-1 ml-3 text-left whitespace-nowrap" sidebar-toggle-item>E-commerce</span>
<svg sidebar-toggle-item class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"></path>
</svg>
</button>
<ul id="dropdown-example" class="hidden py-2 space-y-2">
<li>
<a href="#"
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700">Products</a>
</li>
<li>
<a href="#"
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700">Billing</a>
</li>
<li>
<a href="#"
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700">Invoice</a>
</li>
</ul>
</li>
<li>
<a href="#"
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<svg aria-hidden="true"
class="flex-shrink-0 w-6 h-6 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"
fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path
d="M5 3a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2V5a2 2 0 00-2-2H5zM5 11a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2v-2a2 2 0 00-2-2H5zM11 5a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V5zM11 13a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"></path>
</svg>
<span class="flex-1 ml-3 whitespace-nowrap">Kanban</span>
<span
class="inline-flex items-center justify-center px-2 ml-3 text-sm font-medium text-gray-800 bg-gray-200 rounded-full dark:bg-gray-700 dark:text-gray-300">Pro</span>
</a>
</li>
<li>
<a href="#"
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<svg aria-hidden="true"
class="flex-shrink-0 w-6 h-6 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"
fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path
d="M8.707 7.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l2-2a1 1 0 00-1.414-1.414L11 7.586V3a1 1 0 10-2 0v4.586l-.293-.293z"></path>
<path
d="M3 5a2 2 0 012-2h1a1 1 0 010 2H5v7h2l1 2h4l1-2h2V5h-1a1 1 0 110-2h1a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V5z"></path>
</svg>
<span class="flex-1 ml-3 whitespace-nowrap">Inbox</span>
<span
class="inline-flex items-center justify-center w-3 h-3 p-3 ml-3 text-sm font-medium text-blue-800 bg-blue-100 rounded-full dark:bg-blue-900 dark:text-blue-300">3</span>
</a>
</li>
<li>
<a href="#"
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<svg aria-hidden="true"
class="flex-shrink-0 w-6 h-6 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"
fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"
clip-rule="evenodd"></path>
</svg>
<span class="flex-1 ml-3 whitespace-nowrap">Users</span>
</a>
</li>
<li>
<a href="#"
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<svg aria-hidden="true"
class="flex-shrink-0 w-6 h-6 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"
fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M10 2a4 4 0 00-4 4v1H5a1 1 0 00-.994.89l-1 9A1 1 0 004 18h12a1 1 0 00.994-1.11l-1-9A1 1 0 0015 7h-1V6a4 4 0 00-4-4zm2 5V6a2 2 0 10-4 0v1h4zm-6 3a1 1 0 112 0 1 1 0 01-2 0zm7-1a1 1 0 100 2 1 1 0 000-2z"
clip-rule="evenodd"></path>
</svg>
<span class="flex-1 ml-3 whitespace-nowrap">Products</span>
</a>
</li>
<li>
<a href="#"
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<svg aria-hidden="true"
class="flex-shrink-0 w-6 h-6 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"
fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M3 3a1 1 0 00-1 1v12a1 1 0 102 0V4a1 1 0 00-1-1zm10.293 9.293a1 1 0 001.414 1.414l3-3a1 1 0 000-1.414l-3-3a1 1 0 10-1.414 1.414L14.586 9H7a1 1 0 100 2h7.586l-1.293 1.293z"
clip-rule="evenodd"></path>
</svg>
<span class="flex-1 ml-3 whitespace-nowrap">Sign In</span>
</a>
</li>
<li>
<a href="#"
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<svg aria-hidden="true"
class="flex-shrink-0 w-6 h-6 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"
fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M5 4a3 3 0 00-3 3v6a3 3 0 003 3h10a3 3 0 003-3V7a3 3 0 00-3-3H5zm-1 9v-1h5v2H5a1 1 0 01-1-1zm7 1h4a1 1 0 001-1v-1h-5v2zm0-4h5V8h-5v2zM9 8H4v2h5V8z"
clip-rule="evenodd"></path>
</svg>
<span class="flex-1 ml-3 whitespace-nowrap">Sign Up</span>
</a>
</li>
</ul>
</div>
</aside>
<div class="p-4 sm:ml-64">
<div class="p-4 border-2 border-gray-200 border-dashed rounded-lg dark:border-gray-700">
<div class="grid grid-cols-3 gap-4 mb-4">
<div class="flex items-center justify-center h-24 rounded bg-gray-50 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="flex items-center justify-center h-24 rounded bg-gray-50 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="flex items-center justify-center h-24 rounded bg-gray-50 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
</div>
<div class="flex items-center justify-center h-48 mb-4 rounded bg-gray-50 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div class="flex items-center justify-center rounded bg-gray-50 h-28 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="flex items-center justify-center rounded bg-gray-50 h-28 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="flex items-center justify-center rounded bg-gray-50 h-28 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="flex items-center justify-center rounded bg-gray-50 h-28 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
</div>
<div class="flex items-center justify-center h-48 mb-4 rounded bg-gray-50 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="grid grid-cols-2 gap-4">
<div class="flex items-center justify-center rounded bg-gray-50 h-28 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="flex items-center justify-center rounded bg-gray-50 h-28 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="flex items-center justify-center rounded bg-gray-50 h-28 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
<div class="flex items-center justify-center rounded bg-gray-50 h-28 dark:bg-gray-800">
<p class="text-2xl text-gray-400 dark:text-gray-500">+</p>
</div>
</div>
</div>
</div>
</body>
<script src="{{ asset('js/app.js') }}"></script>
<script src="{{ asset('js/flowbite.js') }}"></script>
<script src="{{ asset('js/jquery.js') }}"></script>
</html>

View File

@ -5,7 +5,10 @@
* https://www.x-lf.com/
*/
use App\Http\Controllers\Authme;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Route;
/*
@ -19,6 +22,17 @@
|
*/
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
Route::middleware('auth')->get('/user', function (Request $request) {
return $request->user();
});
Route::prefix('api')->group(function () {
Route::prefix('auth')->group(function () {
Route::post('login',[Authme::class,'Login'])->name('api.auth.login');
Route::post('register',[Authme::class,'Register'])->name('api.auth.register');
Route::match(['get','post'],'logout',function () {
Auth::logout();
return Response::redirectTo('');
})->name('logout');
});
});

View File

@ -19,5 +19,5 @@
*/
Broadcast::channel('App.Models.User.{id}', function ($user, $id) {
return (int)$user->id === (int)$id;
return (int) $user->id === (int) $id;
});

View File

@ -5,6 +5,8 @@
* https://www.x-lf.com/
*/
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Route;
/*
@ -20,4 +22,27 @@
Route::get('/', function () {
return view('welcome');
})->name('home');
Route::prefix('console')->middleware('auth')->group(function () {
Route::get('dashboard', function () {
return view('console.dashboard');
})->name('console.dashboard');
});
Route::prefix('auth')->group(function () {
Route::redirect('','auth/login');
Route::get('login', function () {
return view('auth.login');
})->name('login');
Route::get('register',function () {
return view('auth.register');
})->name('register');
Route::get('forgotpassword',function () {
return view('auth.forgotpassword');
})->name('forgotpassword');
Route::match(['get','post'],'logout',function () {
Auth::logout();
return Response::redirectTo('');
})->name('logout');
});

View File

@ -19,8 +19,8 @@
// This file allows us to emulate Apache's "mod_rewrite" functionality from the
// built-in PHP web server. This provides a convenient way to test a Laravel
// application without having installed a "real" web server software here.
if ($uri !== '/' && file_exists(__DIR__ . '/public' . $uri)) {
if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
return false;
}
require_once __DIR__ . '/public/index.php';
require_once __DIR__.'/public/index.php';

22
tailwind.config.js Normal file
View File

@ -0,0 +1,22 @@
/*
* Copyright © 2016 - 2023 筱锋xiao_lfeng. All Rights Reserved.
* 开发开源遵循 MIT 许可若需商用请联系开发者
* https://www.x-lf.com/
*/
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
"./resources/**/*.vue",
"./node_modules/flowbite/**/*.js"
],
theme: {
extend: {},
},
plugins: [
require('@tailwindcss/forms'),
require('flowbite/plugin'),
],
}

View File

@ -8,18 +8,17 @@
namespace Tests;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Foundation\Application;
trait CreatesApplication
{
/**
* Creates the application.
*
* @return Application
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
$app = require __DIR__ . '/../bootstrap/app.php';
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();

View File

@ -19,5 +19,5 @@ const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
//
require("tailwindcss")
]);