✨ 迁移至 laravel 9
This commit is contained in:
@@ -17,7 +17,7 @@ DB_PASSWORD=
|
|||||||
|
|
||||||
BROADCAST_DRIVER=log
|
BROADCAST_DRIVER=log
|
||||||
CACHE_DRIVER=file
|
CACHE_DRIVER=file
|
||||||
FILESYSTEM_DRIVER=public
|
FILESYSTEM_DISK=public
|
||||||
QUEUE_CONNECTION=sync
|
QUEUE_CONNECTION=sync
|
||||||
SESSION_DRIVER=file
|
SESSION_DRIVER=file
|
||||||
SESSION_LIFETIME=120
|
SESSION_LIFETIME=120
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
- Email: i@wispx.cn
|
- Email: i@wispx.cn
|
||||||
|
|
||||||
### 💰 捐赠
|
### 💰 捐赠
|
||||||
Lsky Pro 的开发和更新等,都是作者在空余时间独立开发,并免费开源使用,如果您认可我的作品,并且觉得对你有所帮助我愿意接受来自各方面的捐赠😃。
|
Lsky Pro 的开发和更新等,都是作者在空余时间独立开发,并免费开源使用,如果您认可我的作品,并且觉得对你有所帮助我愿意接受来自各方面的捐赠😃。
|
||||||
<table width="100%">
|
<table width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<th>支付宝</th>
|
<th>支付宝</th>
|
||||||
|
|||||||
@@ -2,21 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use BenSampo\Enum\Enum;
|
final class ConfigKey
|
||||||
|
|
||||||
/**
|
|
||||||
* @method static static IsEnableRegistration()
|
|
||||||
* @method static static IsEnableGallery()
|
|
||||||
* @method static static SiteName()
|
|
||||||
* @method static static SiteKeywords()
|
|
||||||
* @method static static SiteDescription()
|
|
||||||
* @method static static IcpNo()
|
|
||||||
* @method static static IsAllowGuestUpload()
|
|
||||||
* @method static static UserInitialCapacity()
|
|
||||||
* @method static static MailConfigs()
|
|
||||||
* @method static static GuestGroupConfigs()
|
|
||||||
*/
|
|
||||||
final class ConfigKey extends Enum
|
|
||||||
{
|
{
|
||||||
/** @var string 是否启用注册 */
|
/** @var string 是否启用注册 */
|
||||||
const IsEnableRegistration = 'is_enable_registration';
|
const IsEnableRegistration = 'is_enable_registration';
|
||||||
|
|||||||
@@ -2,22 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use BenSampo\Enum\Enum;
|
final class GroupConfigKey
|
||||||
|
|
||||||
/**
|
|
||||||
* @method static static MaximumFileSize()
|
|
||||||
* @method static static ConcurrentUploadNum()
|
|
||||||
* @method static static IsUploadNeedsReview()
|
|
||||||
* @method static static LimitPerMinute()
|
|
||||||
* @method static static LimitPerHour()
|
|
||||||
* @method static static LimitPerDay()
|
|
||||||
* @method static static LimitPerWeek()
|
|
||||||
* @method static static LimitPerMonth()
|
|
||||||
* @method static static AcceptedFileSuffixes()
|
|
||||||
* @method static static PathNamingRule()
|
|
||||||
* @method static static FileNamingRule()
|
|
||||||
*/
|
|
||||||
final class GroupConfigKey extends Enum
|
|
||||||
{
|
{
|
||||||
/** @var string 最大文件大小 */
|
/** @var string 最大文件大小 */
|
||||||
const MaximumFileSize = 'maximum_file_size';
|
const MaximumFileSize = 'maximum_file_size';
|
||||||
|
|||||||
@@ -2,13 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use BenSampo\Enum\Enum;
|
final class ImagePermission
|
||||||
|
|
||||||
/**
|
|
||||||
* @method static static Public()
|
|
||||||
* @method static static Private()
|
|
||||||
*/
|
|
||||||
final class ImagePermission extends Enum
|
|
||||||
{
|
{
|
||||||
const Public = 1; // 公开
|
const Public = 1; // 公开
|
||||||
const Private = 0; // 私有
|
const Private = 0; // 私有
|
||||||
|
|||||||
@@ -2,18 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Enums\Mail;
|
namespace App\Enums\Mail;
|
||||||
|
|
||||||
use BenSampo\Enum\Enum;
|
final class SmtpOption
|
||||||
|
|
||||||
/**
|
|
||||||
* @method static static Host()
|
|
||||||
* @method static static Port()
|
|
||||||
* @method static static Encryption()
|
|
||||||
* @method static static Username()
|
|
||||||
* @method static static Password()
|
|
||||||
* @method static static Timeout()
|
|
||||||
* @method static static AuthMode()
|
|
||||||
*/
|
|
||||||
final class SmtpOption extends Enum
|
|
||||||
{
|
{
|
||||||
/** @var string 主机地址 */
|
/** @var string 主机地址 */
|
||||||
const Host = 'host';
|
const Host = 'host';
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Enums\Strategy;
|
namespace App\Enums\Strategy;
|
||||||
|
|
||||||
use BenSampo\Enum\Enum;
|
final class KodoOption
|
||||||
|
|
||||||
final class KodoOption extends Enum
|
|
||||||
{
|
{
|
||||||
/** @var string 访问域名 */
|
/** @var string 访问域名 */
|
||||||
const Domain = 'domain';
|
const Domain = 'domain';
|
||||||
|
|||||||
@@ -2,13 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Enums\Strategy;
|
namespace App\Enums\Strategy;
|
||||||
|
|
||||||
use BenSampo\Enum\Enum;
|
final class LocalOption
|
||||||
|
|
||||||
/**
|
|
||||||
* @method static static Domain()
|
|
||||||
* @method static static Root()
|
|
||||||
*/
|
|
||||||
final class LocalOption extends Enum
|
|
||||||
{
|
{
|
||||||
/** @var string 访问域名 */
|
/** @var string 访问域名 */
|
||||||
const Domain = 'domain';
|
const Domain = 'domain';
|
||||||
|
|||||||
@@ -2,20 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use BenSampo\Enum\Enum;
|
final class StrategyKey
|
||||||
|
|
||||||
/**
|
|
||||||
* @method static static Local()
|
|
||||||
* @method static static S3()
|
|
||||||
* @method static static Oss()
|
|
||||||
* @method static static Cos()
|
|
||||||
* @method static static Kodo()
|
|
||||||
* @method static static Uss()
|
|
||||||
* @method static static Sftp()
|
|
||||||
* @method static static Ftp()
|
|
||||||
* @method static static Webdav()
|
|
||||||
*/
|
|
||||||
final class StrategyKey extends Enum
|
|
||||||
{
|
{
|
||||||
/** @var int 本地 */
|
/** @var int 本地 */
|
||||||
const Local = 1;
|
const Local = 1;
|
||||||
|
|||||||
@@ -2,14 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use BenSampo\Enum\Enum;
|
final class UserConfigKey
|
||||||
|
|
||||||
/**
|
|
||||||
* @method static static DefaultAlbum()
|
|
||||||
* @method static static DefaultStrategy()
|
|
||||||
* @method static static IsAutoClearPreview()
|
|
||||||
*/
|
|
||||||
final class UserConfigKey extends Enum
|
|
||||||
{
|
{
|
||||||
/** @var string 默认相册 */
|
/** @var string 默认相册 */
|
||||||
const DefaultAlbum = 'default_album';
|
const DefaultAlbum = 'default_album';
|
||||||
|
|||||||
@@ -2,13 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use BenSampo\Enum\Enum;
|
final class UserStatus
|
||||||
|
|
||||||
/**
|
|
||||||
* @method static static Normal()
|
|
||||||
* @method static static Frozen()
|
|
||||||
*/
|
|
||||||
final class UserStatus extends Enum
|
|
||||||
{
|
{
|
||||||
/** @var int 正常 */
|
/** @var int 正常 */
|
||||||
const Normal = 1;
|
const Normal = 1;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
use App\Enums\UserStatus;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Providers\RouteServiceProvider;
|
use App\Providers\RouteServiceProvider;
|
||||||
@@ -40,14 +39,10 @@ class RegisteredUserController extends Controller
|
|||||||
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// TODO 获取默认组
|
|
||||||
|
|
||||||
$user = User::create([
|
$user = User::create([
|
||||||
'name' => $request->name,
|
'name' => $request->name,
|
||||||
'email' => $request->email,
|
'email' => $request->email,
|
||||||
'password' => Hash::make($request->password),
|
'password' => Hash::make($request->password),
|
||||||
'registered_ip' => $request->ip(),
|
|
||||||
'status' => UserStatus::Normal,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
event(new Registered($user));
|
event(new Registered($user));
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class RouteServiceProvider extends ServiceProvider
|
|||||||
protected function configureRateLimiting()
|
protected function configureRateLimiting()
|
||||||
{
|
{
|
||||||
RateLimiter::for('api', function (Request $request) {
|
RateLimiter::for('api', function (Request $request) {
|
||||||
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
|
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,10 @@ use Illuminate\Support\Collection;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Intervention\Image\Facades\Image as InterventionImage;
|
use Intervention\Image\Facades\Image as InterventionImage;
|
||||||
use League\Flysystem\Adapter\Local;
|
|
||||||
use League\Flysystem\AdapterInterface;
|
|
||||||
use League\Flysystem\Filesystem;
|
use League\Flysystem\Filesystem;
|
||||||
|
use League\Flysystem\FilesystemAdapter;
|
||||||
|
use League\Flysystem\FilesystemException;
|
||||||
|
use League\Flysystem\Local\LocalFilesystemAdapter;
|
||||||
use Overtrue\Flysystem\Qiniu\QiniuAdapter;
|
use Overtrue\Flysystem\Qiniu\QiniuAdapter;
|
||||||
|
|
||||||
class ImageService
|
class ImageService
|
||||||
@@ -149,9 +150,14 @@ class ImageService
|
|||||||
})->where('md5', $image->md5)->where('sha1', $image->sha1)->first();
|
})->where('md5', $image->md5)->where('sha1', $image->sha1)->first();
|
||||||
if (is_null($existing)) {
|
if (is_null($existing)) {
|
||||||
$handle = fopen($file, 'r');
|
$handle = fopen($file, 'r');
|
||||||
if (! $filesystem->putStream($pathname, $handle) || ! fclose($handle)) {
|
try {
|
||||||
|
$filesystem->writeStream($pathname, $handle);
|
||||||
|
} catch (FilesystemException $e) {
|
||||||
throw new UploadException('图片上传失败');
|
throw new UploadException('图片上传失败');
|
||||||
}
|
}
|
||||||
|
if (! fclose($handle)) {
|
||||||
|
throw new UploadException('资源关闭失败');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$image->fill($existing->only('path', 'name'));
|
$image->fill($existing->only('path', 'name'));
|
||||||
}
|
}
|
||||||
@@ -170,10 +176,10 @@ class ImageService
|
|||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAdapter(int $disk, Collection $configs): AdapterInterface
|
public function getAdapter(int $disk, Collection $configs): FilesystemAdapter
|
||||||
{
|
{
|
||||||
return match ($disk) {
|
return match ($disk) {
|
||||||
StrategyKey::Local => new Local($configs->get('root') ?: config('filesystems.disks.uploads.root')),
|
StrategyKey::Local => new LocalFilesystemAdapter($configs->get('root') ?: config('filesystems.disks.uploads.root')),
|
||||||
StrategyKey::Kodo => new QiniuAdapter(
|
StrategyKey::Kodo => new QiniuAdapter(
|
||||||
accessKey: $configs->get(KodoOption::AccessKey),
|
accessKey: $configs->get(KodoOption::AccessKey),
|
||||||
secretKey: $configs->get(KodoOption::SecretKey),
|
secretKey: $configs->get(KodoOption::SecretKey),
|
||||||
|
|||||||
@@ -6,23 +6,20 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.0",
|
"php": "^8.0",
|
||||||
"bensampo/laravel-enum": "^4.1",
|
"fruitcake/laravel-cors": "^2.0.5",
|
||||||
"fruitcake/laravel-cors": "^2.0",
|
"guzzlehttp/guzzle": "^7.0.1",
|
||||||
"guzzlehttp/guzzle": "^7.4",
|
|
||||||
"intervention/image": "^2.7",
|
"intervention/image": "^2.7",
|
||||||
"laravel/breeze": "^1.5",
|
"laravel/breeze": "dev-laravel9",
|
||||||
"laravel/framework": "^8.65",
|
"laravel/framework": "^9.0",
|
||||||
"laravel/sanctum": "^2.11",
|
"laravel/sanctum": "^2.11|dev-develop",
|
||||||
"laravel/tinker": "^2.5",
|
"laravel/tinker": "^2.5|dev-develop",
|
||||||
"overtrue/flysystem-qiniu": "~1.0",
|
"overtrue/flysystem-qiniu": "^2.0"
|
||||||
"overtrue/laravel-lang": "~5.0"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"facade/ignition": "^2.5",
|
|
||||||
"fakerphp/faker": "^1.9.1",
|
"fakerphp/faker": "^1.9.1",
|
||||||
"laravel/sail": "^1.0.1",
|
"laravel/sail": "^1.0.1",
|
||||||
"mockery/mockery": "^1.4.4",
|
"mockery/mockery": "^1.4.4",
|
||||||
"nunomaduro/collision": "^5.10",
|
"nunomaduro/collision": "^6.0",
|
||||||
"phpunit/phpunit": "^9.5.10"
|
"phpunit/phpunit": "^9.5.10"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|||||||
1854
composer.lock
generated
1854
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -188,48 +190,8 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'aliases' => [
|
'aliases' => array_merge(Facade::defaultAliases(), [
|
||||||
|
// ...
|
||||||
'App' => Illuminate\Support\Facades\App::class,
|
]),
|
||||||
'Arr' => Illuminate\Support\Arr::class,
|
|
||||||
'Artisan' => Illuminate\Support\Facades\Artisan::class,
|
|
||||||
'Auth' => Illuminate\Support\Facades\Auth::class,
|
|
||||||
'Blade' => Illuminate\Support\Facades\Blade::class,
|
|
||||||
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
|
|
||||||
'Bus' => Illuminate\Support\Facades\Bus::class,
|
|
||||||
'Cache' => Illuminate\Support\Facades\Cache::class,
|
|
||||||
'Config' => Illuminate\Support\Facades\Config::class,
|
|
||||||
'Cookie' => Illuminate\Support\Facades\Cookie::class,
|
|
||||||
'Crypt' => Illuminate\Support\Facades\Crypt::class,
|
|
||||||
'Date' => Illuminate\Support\Facades\Date::class,
|
|
||||||
'DB' => Illuminate\Support\Facades\DB::class,
|
|
||||||
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
|
|
||||||
'Event' => Illuminate\Support\Facades\Event::class,
|
|
||||||
'File' => Illuminate\Support\Facades\File::class,
|
|
||||||
'Gate' => Illuminate\Support\Facades\Gate::class,
|
|
||||||
'Hash' => Illuminate\Support\Facades\Hash::class,
|
|
||||||
'Http' => Illuminate\Support\Facades\Http::class,
|
|
||||||
'Js' => Illuminate\Support\Js::class,
|
|
||||||
'Lang' => Illuminate\Support\Facades\Lang::class,
|
|
||||||
'Log' => Illuminate\Support\Facades\Log::class,
|
|
||||||
'Mail' => Illuminate\Support\Facades\Mail::class,
|
|
||||||
'Notification' => Illuminate\Support\Facades\Notification::class,
|
|
||||||
'Password' => Illuminate\Support\Facades\Password::class,
|
|
||||||
'Queue' => Illuminate\Support\Facades\Queue::class,
|
|
||||||
'RateLimiter' => Illuminate\Support\Facades\RateLimiter::class,
|
|
||||||
'Redirect' => Illuminate\Support\Facades\Redirect::class,
|
|
||||||
// 'Redis' => Illuminate\Support\Facades\Redis::class,
|
|
||||||
'Request' => Illuminate\Support\Facades\Request::class,
|
|
||||||
'Response' => Illuminate\Support\Facades\Response::class,
|
|
||||||
'Route' => Illuminate\Support\Facades\Route::class,
|
|
||||||
'Schema' => Illuminate\Support\Facades\Schema::class,
|
|
||||||
'Session' => Illuminate\Support\Facades\Session::class,
|
|
||||||
'Storage' => Illuminate\Support\Facades\Storage::class,
|
|
||||||
'Str' => Illuminate\Support\Str::class,
|
|
||||||
'URL' => Illuminate\Support\Facades\URL::class,
|
|
||||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
|
||||||
'View' => Illuminate\Support\Facades\View::class,
|
|
||||||
|
|
||||||
],
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ return [
|
|||||||
'cluster' => env('PUSHER_APP_CLUSTER'),
|
'cluster' => env('PUSHER_APP_CLUSTER'),
|
||||||
'useTLS' => true,
|
'useTLS' => true,
|
||||||
],
|
],
|
||||||
|
'client_options' => [
|
||||||
|
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
|
||||||
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
'ably' => [
|
'ably' => [
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ return [
|
|||||||
'charset' => 'utf8',
|
'charset' => 'utf8',
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
'prefix_indexes' => true,
|
'prefix_indexes' => true,
|
||||||
'schema' => 'public',
|
'search_path' => 'public',
|
||||||
'sslmode' => 'prefer',
|
'sslmode' => 'prefer',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'default' => env('FILESYSTEM_DRIVER', 'local'),
|
'default' => env('FILESYSTEM_DISK', 'local'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@@ -48,6 +48,18 @@ return [
|
|||||||
'url' => env('APP_URL').'/uploads',
|
'url' => env('APP_URL').'/uploads',
|
||||||
'visibility' => 'public',
|
'visibility' => 'public',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
's3' => [
|
||||||
|
'driver' => 's3',
|
||||||
|
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||||
|
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||||
|
'region' => env('AWS_DEFAULT_REGION'),
|
||||||
|
'bucket' => env('AWS_BUCKET'),
|
||||||
|
'url' => env('AWS_URL'),
|
||||||
|
'endpoint' => env('AWS_ENDPOINT'),
|
||||||
|
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
|
||||||
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ return [
|
|||||||
'username' => env('MAIL_USERNAME'),
|
'username' => env('MAIL_USERNAME'),
|
||||||
'password' => env('MAIL_PASSWORD'),
|
'password' => env('MAIL_PASSWORD'),
|
||||||
'timeout' => null,
|
'timeout' => null,
|
||||||
'auth_mode' => null,
|
|
||||||
],
|
],
|
||||||
|
|
||||||
'ses' => [
|
'ses' => [
|
||||||
|
|||||||
7
lang/en.json
Normal file
7
lang/en.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"The :attribute must contain at least one letter.": "The :attribute must contain at least one letter.",
|
||||||
|
"The :attribute must contain at least one number.": "The :attribute must contain at least one number.",
|
||||||
|
"The :attribute must contain at least one symbol.": "The :attribute must contain at least one symbol.",
|
||||||
|
"The :attribute must contain at least one uppercase and one lowercase letter.": "The :attribute must contain at least one uppercase and one lowercase letter.",
|
||||||
|
"The given :attribute has appeared in a data leak. Please choose a different :attribute.": "The given :attribute has appeared in a data leak. Please choose a different :attribute."
|
||||||
|
}
|
||||||
2913
package-lock.json
generated
2913
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -10,11 +10,16 @@
|
|||||||
"production": "mix --production"
|
"production": "mix --production"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
|
||||||
"@tailwindcss/forms": "^0.4.0",
|
"@tailwindcss/forms": "^0.4.0",
|
||||||
"alpinejs": "^3.4.2",
|
"alpinejs": "^3.4.2",
|
||||||
"autoprefixer": "^10.1.0",
|
"autoprefixer": "^10.1.0",
|
||||||
"axios": "^0.21",
|
"axios": "^0.21",
|
||||||
|
"laravel-mix": "^6.0.6",
|
||||||
|
"lodash": "^4.17.19",
|
||||||
|
"postcss": "^8.2.1",
|
||||||
|
"postcss-import": "^14.0.1",
|
||||||
|
"tailwindcss": "^3.0.0",
|
||||||
|
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||||
"blueimp-canvas-to-blob": "^3.29.0",
|
"blueimp-canvas-to-blob": "^3.29.0",
|
||||||
"blueimp-file-upload": "^10.32.0",
|
"blueimp-file-upload": "^10.32.0",
|
||||||
"blueimp-load-image": "^5.16.0",
|
"blueimp-load-image": "^5.16.0",
|
||||||
@@ -25,14 +30,9 @@
|
|||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"jquery.photoswipe": "^1.1.1",
|
"jquery.photoswipe": "^1.1.1",
|
||||||
"justifiedGallery": "^3.8.1",
|
"justifiedGallery": "^3.8.1",
|
||||||
"laravel-mix": "^6.0.39",
|
|
||||||
"less": "^4.1.2",
|
"less": "^4.1.2",
|
||||||
"less-loader": "^10.2.0",
|
"less-loader": "^10.2.0",
|
||||||
"lodash": "^4.17.19",
|
|
||||||
"postcss": "^8.2.1",
|
|
||||||
"postcss-import": "^12.0.1",
|
|
||||||
"resolve-url-loader": "^4.0.0",
|
"resolve-url-loader": "^4.0.0",
|
||||||
"tailwindcss": "^3.0.0",
|
|
||||||
"toastr": "^2.1.4",
|
"toastr": "^2.1.4",
|
||||||
"viewerjs": "^1.10.2",
|
"viewerjs": "^1.10.2",
|
||||||
"sweetalert2": "^11.3.3"
|
"sweetalert2": "^11.3.3"
|
||||||
|
|||||||
610
public/css/app.css
vendored
610
public/css/app.css
vendored
File diff suppressed because it is too large
Load Diff
0
public/css/justified-gallery/justifiedGallery.min.css
vendored
Executable file → Normal file
0
public/css/justified-gallery/justifiedGallery.min.css
vendored
Executable file → Normal file
0
public/css/viewer-js/viewer.min.css
vendored
Executable file → Normal file
0
public/css/viewer-js/viewer.min.css
vendored
Executable file → Normal file
@@ -16,8 +16,8 @@ define('LARAVEL_START', microtime(true));
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (file_exists(__DIR__.'/../storage/framework/maintenance.php')) {
|
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
|
||||||
require __DIR__.'/../storage/framework/maintenance.php';
|
require $maintenance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
0
public/js/blueimp-file-upload/jquery.fileupload.js
vendored
Executable file → Normal file
0
public/js/blueimp-file-upload/jquery.fileupload.js
vendored
Executable file → Normal file
0
public/js/blueimp-file-upload/jquery.iframe-transport.js
vendored
Executable file → Normal file
0
public/js/blueimp-file-upload/jquery.iframe-transport.js
vendored
Executable file → Normal file
0
public/js/blueimp-file-upload/jquery.ui.widget.js
vendored
Executable file → Normal file
0
public/js/blueimp-file-upload/jquery.ui.widget.js
vendored
Executable file → Normal file
0
public/js/blueimp-load-image/load-image.all.min.js
vendored
Executable file → Normal file
0
public/js/blueimp-load-image/load-image.all.min.js
vendored
Executable file → Normal file
0
public/js/clipboard/clipboard.min.js
vendored
Executable file → Normal file
0
public/js/clipboard/clipboard.min.js
vendored
Executable file → Normal file
0
public/js/clipboard/index.browser.js
vendored
Executable file → Normal file
0
public/js/clipboard/index.browser.js
vendored
Executable file → Normal file
0
public/js/dragselect/ds.min.js
vendored
Executable file → Normal file
0
public/js/dragselect/ds.min.js
vendored
Executable file → Normal file
0
public/js/justified-gallery/jquery.justifiedGallery.min.js
vendored
Executable file → Normal file
0
public/js/justified-gallery/jquery.justifiedGallery.min.js
vendored
Executable file → Normal file
0
public/js/viewer-js/viewer.min.js
vendored
Executable file → Normal file
0
public/js/viewer-js/viewer.min.js
vendored
Executable file → Normal file
@@ -1,28 +0,0 @@
|
|||||||
<!--
|
|
||||||
Rewrites requires Microsoft URL Rewrite Module for IIS
|
|
||||||
Download: https://www.iis.net/downloads/microsoft/url-rewrite
|
|
||||||
Debug Help: https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/using-failed-request-tracing-to-trace-rewrite-rules
|
|
||||||
-->
|
|
||||||
<configuration>
|
|
||||||
<system.webServer>
|
|
||||||
<rewrite>
|
|
||||||
<rules>
|
|
||||||
<rule name="Imported Rule 1" stopProcessing="true">
|
|
||||||
<match url="^(.*)/$" ignoreCase="false" />
|
|
||||||
<conditions>
|
|
||||||
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
|
|
||||||
</conditions>
|
|
||||||
<action type="Redirect" redirectType="Permanent" url="/{R:1}" />
|
|
||||||
</rule>
|
|
||||||
<rule name="Imported Rule 2" stopProcessing="true">
|
|
||||||
<match url="^" ignoreCase="false" />
|
|
||||||
<conditions>
|
|
||||||
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
|
|
||||||
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
|
|
||||||
</conditions>
|
|
||||||
<action type="Rewrite" url="index.php" />
|
|
||||||
</rule>
|
|
||||||
</rules>
|
|
||||||
</rewrite>
|
|
||||||
</system.webServer>
|
|
||||||
</configuration>
|
|
||||||
@@ -128,6 +128,9 @@
|
|||||||
url: '{{ route('upload') }}',
|
url: '{{ route('upload') }}',
|
||||||
autoUpload: false,
|
autoUpload: false,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||||
|
},
|
||||||
limitMultiFileUploads: 1,
|
limitMultiFileUploads: 1,
|
||||||
limitConcurrentUploads: 3,
|
limitConcurrentUploads: 3,
|
||||||
pasteZone: $(document),
|
pasteZone: $(document),
|
||||||
@@ -201,12 +204,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
fail: (e, data) => {
|
fail: (e, data) => {
|
||||||
// 重新显示上传按钮
|
if (data.errorThrown !== 'abort') {
|
||||||
data.$preview.find('[data-operate="upload"]').show();
|
// 重新显示上传按钮
|
||||||
if (data.jqXHR.status === 419) {
|
data.$preview.find('[data-operate="upload"]').show();
|
||||||
return setStatus(data, UPLOAD_ERROR, '令牌错误,请刷新网页重试');
|
if (data.jqXHR.status === 419) {
|
||||||
|
return setStatus(data, UPLOAD_ERROR, '令牌错误,请刷新网页重试');
|
||||||
|
}
|
||||||
|
return setStatus(data, UPLOAD_ERROR, '服务端异常,请稍后重试');
|
||||||
}
|
}
|
||||||
return setStatus(data, UPLOAD_ERROR, '服务端异常,请稍后重试');
|
|
||||||
},
|
},
|
||||||
// 等同于jq的complete
|
// 等同于jq的complete
|
||||||
always: (e, data) => {
|
always: (e, data) => {
|
||||||
@@ -229,7 +234,8 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$previews.on('click', '[data-operate]', function () {
|
$previews.on('click', '[data-operate]', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
let $preview = $(this).closest('[data-id]');
|
let $preview = $(this).closest('[data-id]');
|
||||||
let method = $(this).data('operate');
|
let method = $(this).data('operate');
|
||||||
let id = $preview.data('id');
|
let id = $preview.data('id');
|
||||||
|
|||||||
92
resources/views/layouts/navigation.blade.php
Normal file
92
resources/views/layouts/navigation.blade.php
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<nav x-data="{ open: false }" class="bg-white border-b border-gray-100">
|
||||||
|
<!-- Primary Navigation Menu -->
|
||||||
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
<div class="flex justify-between h-16">
|
||||||
|
<div class="flex">
|
||||||
|
<!-- Logo -->
|
||||||
|
<div class="shrink-0 flex items-center">
|
||||||
|
<a href="{{ route('dashboard') }}">
|
||||||
|
<x-application-logo class="block h-10 w-auto fill-current text-gray-600" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Navigation Links -->
|
||||||
|
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
|
||||||
|
<x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
|
||||||
|
{{ __('Dashboard') }}
|
||||||
|
</x-nav-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Settings Dropdown -->
|
||||||
|
<div class="hidden sm:flex sm:items-center sm:ml-6">
|
||||||
|
<x-dropdown align="right" width="48">
|
||||||
|
<x-slot name="trigger">
|
||||||
|
<button class="flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out">
|
||||||
|
<div>{{ Auth::user()->name }}</div>
|
||||||
|
|
||||||
|
<div class="ml-1">
|
||||||
|
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||||
|
<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" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
<x-slot name="content">
|
||||||
|
<!-- Authentication -->
|
||||||
|
<form method="POST" action="{{ route('logout') }}">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<x-dropdown-link :href="route('logout')"
|
||||||
|
onclick="event.preventDefault();
|
||||||
|
this.closest('form').submit();">
|
||||||
|
{{ __('Log Out') }}
|
||||||
|
</x-dropdown-link>
|
||||||
|
</form>
|
||||||
|
</x-slot>
|
||||||
|
</x-dropdown>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hamburger -->
|
||||||
|
<div class="-mr-2 flex items-center sm:hidden">
|
||||||
|
<button @click="open = ! open" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out">
|
||||||
|
<svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
|
||||||
|
<path :class="{'hidden': open, 'inline-flex': ! open }" class="inline-flex" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
||||||
|
<path :class="{'hidden': ! open, 'inline-flex': open }" class="hidden" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Responsive Navigation Menu -->
|
||||||
|
<div :class="{'block': open, 'hidden': ! open}" class="hidden sm:hidden">
|
||||||
|
<div class="pt-2 pb-3 space-y-1">
|
||||||
|
<x-responsive-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
|
||||||
|
{{ __('Dashboard') }}
|
||||||
|
</x-responsive-nav-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Responsive Settings Options -->
|
||||||
|
<div class="pt-4 pb-1 border-t border-gray-200">
|
||||||
|
<div class="px-4">
|
||||||
|
<div class="font-medium text-base text-gray-800">{{ Auth::user()->name }}</div>
|
||||||
|
<div class="font-medium text-sm text-gray-500">{{ Auth::user()->email }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3 space-y-1">
|
||||||
|
<!-- Authentication -->
|
||||||
|
<form method="POST" action="{{ route('logout') }}">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<x-responsive-nav-link :href="route('logout')"
|
||||||
|
onclick="event.preventDefault();
|
||||||
|
this.closest('form').submit();">
|
||||||
|
{{ __('Log Out') }}
|
||||||
|
</x-responsive-nav-link>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
@@ -10,42 +10,55 @@ use App\Http\Controllers\Auth\RegisteredUserController;
|
|||||||
use App\Http\Controllers\Auth\VerifyEmailController;
|
use App\Http\Controllers\Auth\VerifyEmailController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get('/register', [RegisteredUserController::class, 'create'])->middleware('guest')->name('register');
|
Route::get('/register', [RegisteredUserController::class, 'create'])
|
||||||
Route::post('/register', [RegisteredUserController::class, 'store'])->middleware('guest');
|
->middleware('guest')
|
||||||
Route::get('/login', [AuthenticatedSessionController::class, 'create'])->middleware('guest')->name('login');
|
->name('register');
|
||||||
Route::post('/login', [AuthenticatedSessionController::class, 'store'])->middleware('guest');
|
|
||||||
Route::get('/forgot-password', [PasswordResetLinkController::class, 'create'])->middleware('guest')
|
Route::post('/register', [RegisteredUserController::class, 'store'])
|
||||||
->name('password.request');
|
->middleware('guest');
|
||||||
|
|
||||||
|
Route::get('/login', [AuthenticatedSessionController::class, 'create'])
|
||||||
|
->middleware('guest')
|
||||||
|
->name('login');
|
||||||
|
|
||||||
|
Route::post('/login', [AuthenticatedSessionController::class, 'store'])
|
||||||
|
->middleware('guest');
|
||||||
|
|
||||||
|
Route::get('/forgot-password', [PasswordResetLinkController::class, 'create'])
|
||||||
|
->middleware('guest')
|
||||||
|
->name('password.request');
|
||||||
|
|
||||||
Route::post('/forgot-password', [PasswordResetLinkController::class, 'store'])
|
Route::post('/forgot-password', [PasswordResetLinkController::class, 'store'])
|
||||||
->middleware('guest')
|
->middleware('guest')
|
||||||
->name('password.email');
|
->name('password.email');
|
||||||
|
|
||||||
Route::get('/reset-password/{token}', [NewPasswordController::class, 'create'])
|
Route::get('/reset-password/{token}', [NewPasswordController::class, 'create'])
|
||||||
->middleware('guest')
|
->middleware('guest')
|
||||||
->name('password.reset');
|
->name('password.reset');
|
||||||
|
|
||||||
Route::post('/reset-password', [NewPasswordController::class, 'store'])
|
Route::post('/reset-password', [NewPasswordController::class, 'store'])
|
||||||
->middleware('guest')
|
->middleware('guest')
|
||||||
->name('password.update');
|
->name('password.update');
|
||||||
|
|
||||||
Route::get('/verify-email', [EmailVerificationPromptController::class, '__invoke'])
|
Route::get('/verify-email', [EmailVerificationPromptController::class, '__invoke'])
|
||||||
->middleware('auth')
|
->middleware('auth')
|
||||||
->name('verification.notice');
|
->name('verification.notice');
|
||||||
|
|
||||||
Route::get('/verify-email/{id}/{hash}', [VerifyEmailController::class, '__invoke'])
|
Route::get('/verify-email/{id}/{hash}', [VerifyEmailController::class, '__invoke'])
|
||||||
->middleware(['auth', 'signed', 'throttle:6,1'])
|
->middleware(['auth', 'signed', 'throttle:6,1'])
|
||||||
->name('verification.verify');
|
->name('verification.verify');
|
||||||
|
|
||||||
Route::post('/email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
|
Route::post('/email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
|
||||||
->middleware(['auth', 'throttle:6,1'])
|
->middleware(['auth', 'throttle:6,1'])
|
||||||
->name('verification.send');
|
->name('verification.send');
|
||||||
|
|
||||||
Route::get('/confirm-password', [ConfirmablePasswordController::class, 'show'])
|
Route::get('/confirm-password', [ConfirmablePasswordController::class, 'show'])
|
||||||
->middleware('auth')
|
->middleware('auth')
|
||||||
->name('password.confirm');
|
->name('password.confirm');
|
||||||
|
|
||||||
Route::post('/confirm-password', [ConfirmablePasswordController::class, 'store'])
|
Route::post('/confirm-password', [ConfirmablePasswordController::class, 'store'])
|
||||||
->middleware('auth');
|
->middleware('auth');
|
||||||
|
|
||||||
Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])
|
Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])
|
||||||
->middleware('auth')
|
->middleware('auth')
|
||||||
->name('logout');
|
->name('logout');
|
||||||
|
|||||||
21
server.php
21
server.php
@@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Laravel - A PHP Framework For Web Artisans
|
|
||||||
*
|
|
||||||
* @package Laravel
|
|
||||||
* @author Taylor Otwell <taylor@laravel.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
$uri = urldecode(
|
|
||||||
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 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)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once __DIR__.'/public/index.php';
|
|
||||||
2
storage/app/.gitignore
vendored
2
storage/app/.gitignore
vendored
@@ -1,4 +1,4 @@
|
|||||||
*
|
*
|
||||||
!public/
|
!public/
|
||||||
!uploads
|
!uploads/
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class ExampleTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function test_example()
|
public function test_the_application_returns_a_successful_response()
|
||||||
{
|
{
|
||||||
$response = $this->get('/');
|
$response = $this->get('/');
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class ExampleTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function test_example()
|
public function test_that_true_is_true()
|
||||||
{
|
{
|
||||||
$this->assertTrue(true);
|
$this->assertTrue(true);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user