From 843abacdef57f7e2921a3bfc91ae1c2d58e9a03b Mon Sep 17 00:00:00 2001 From: Wisp X Date: Tue, 1 Mar 2022 11:39:51 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E9=80=82=E9=85=8D=E6=B8=B8?= =?UTF-8?q?=E5=AE=A2=E7=BB=84=E8=83=BD=E4=BD=BF=E7=94=A8=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E5=82=A8=E5=AD=98=E7=9A=84=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Commands/Install.php | 2 - app/Enums/ConfigKey.php | 3 - .../Controllers/Admin/GroupController.php | 58 +++---- .../Controllers/Api/V1/ImageController.php | 4 +- app/Http/Controllers/Controller.php | 14 +- app/Http/Controllers/User/UserController.php | 2 +- app/Http/Requests/Admin/GroupRequest.php | 1 + app/Http/Requests/UserSettingRequest.php | 2 +- app/Models/Group.php | 23 ++- app/Models/Image.php | 12 +- app/Providers/AppServiceProvider.php | 12 +- app/Services/ImageService.php | 142 +++++++++--------- composer.lock | 73 ++++----- config/convention.php | 1 - .../2014_10_10_000000_create_groups_table.php | 1 + database/seeders/InstallSeeder.php | 26 +++- resources/views/admin/group/add.blade.php | 10 +- resources/views/admin/group/edit.blade.php | 25 ++- resources/views/admin/group/index.blade.php | 36 ++--- resources/views/admin/setting/index.blade.php | 4 - resources/views/admin/strategy/add.blade.php | 2 + resources/views/admin/strategy/edit.blade.php | 2 + resources/views/admin/strategy/tips.blade.php | 3 + resources/views/common/api.blade.php | 2 +- resources/views/layouts/app.blade.php | 10 ++ 25 files changed, 240 insertions(+), 230 deletions(-) create mode 100644 resources/views/admin/strategy/tips.blade.php diff --git a/app/Console/Commands/Install.php b/app/Console/Commands/Install.php index 32854bb0..4ed0277f 100644 --- a/app/Console/Commands/Install.php +++ b/app/Console/Commands/Install.php @@ -90,8 +90,6 @@ class Install extends Command )); // 创建锁文件 file_put_contents(base_path('installed.lock'), ''); - // 生成系统本地储存符号链接 - Artisan::call('storage:link'); } catch (\Throwable $e) { $this->warn("Installation error!\n"); $this->error($e->getMessage()); diff --git a/app/Enums/ConfigKey.php b/app/Enums/ConfigKey.php index 63d9ffa6..dee9bfbe 100644 --- a/app/Enums/ConfigKey.php +++ b/app/Enums/ConfigKey.php @@ -16,9 +16,6 @@ final class ConfigKey /** @var string 程序名称 */ const AppName = 'app_name'; - /** @var string 程序url */ - const AppUrl = 'app_url'; - /** @var string 程序版本 */ const AppVersion = 'app_version'; diff --git a/app/Http/Controllers/Admin/GroupController.php b/app/Http/Controllers/Admin/GroupController.php index fc284580..0fb6b8e4 100644 --- a/app/Http/Controllers/Admin/GroupController.php +++ b/app/Http/Controllers/Admin/GroupController.php @@ -4,16 +4,13 @@ declare(strict_types=1); namespace App\Http\Controllers\Admin; -use App\Enums\ConfigKey; use App\Http\Controllers\Controller; use App\Http\Requests\Admin\GroupRequest; -use App\Models\Config; use App\Models\Group; -use App\Utils; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; use Illuminate\Http\Response; -use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\DB; use Illuminate\View\View; class GroupController extends Controller @@ -21,7 +18,7 @@ class GroupController extends Controller public function __construct() { \Illuminate\Support\Facades\View::share([ - 'default' => Utils::config(ConfigKey::Group), + 'default' => Group::getDefaultConfigs(), 'positions' => Group::POSITIONS, 'scenes' => Group::SCENES, ]); @@ -42,44 +39,43 @@ class GroupController extends Controller public function edit(Request $request): View { - if ($request->route('id') == 0) { - $group = new Group([ - 'id' => 0, - 'name' => '系统默认组', - 'configs' => Utils::config(ConfigKey::Group), - ]); - } else { - $group = Group::query()->findOrFail($request->route('id')); - } + $group = Group::query()->findOrFail($request->route('id')); return view('admin.group.edit', compact('group')); } public function create(GroupRequest $request): Response { - $group = new Group(); - $group->fill($request->validated()); - $group->save(); + DB::transaction(function () use ($request) { + $group = new Group(); + $group->fill($request->validated()); + $group->save(); + }); + return $this->success('创建成功'); } public function update(GroupRequest $request): Response { - if ($request->route('id') == 0) { - $configs = Utils::parseConfigs(Group::getDefaultConfigs()->toArray(), $request->validated('configs')); - if (! Config::query()->where('name', ConfigKey::Group)->update([ - 'value' => collect($configs)->toJson(), - ])) { - return $this->error('保存失败'); - } - // 删除配置缓存 - Cache::forget('configs'); - } else { + DB::beginTransaction(); + try { /** @var Group $group */ $group = Group::query()->findOrFail($request->route('id')); $group->fill($request->validated()); - if (!$group->save()) { - return $this->error('保存失败'); + if ($group->isDirty('is_default') && ! $group->is_default) { + if (! Group::query()->where('is_default', true)->where('id', '<>', $group->id)->exists()) { + return $this->error('系统至少需要保留一个默认组'); + } } + if ($group->isDirty('is_guest') && ! $group->is_guest) { + if (! Group::query()->where('is_guest', true)->where('id', '<>', $group->id)->exists()) { + return $this->error('系统至少需要保留一个游客组'); + } + } + $group->save(); + DB::commit(); + } catch (\Throwable $e) { + DB::rollBack(); + return $this->error('保存失败'); } return $this->success('保存成功'); @@ -87,7 +83,11 @@ class GroupController extends Controller public function delete(Request $request): Response { + /** @var Group $group */ if ($group = Group::query()->find($request->route('id'))) { + if ($group->is_default || $group->is_guest) { + return $this->error('默认组和游客组无法删除'); + } $group->delete(); } return $this->success('删除成功'); diff --git a/app/Http/Controllers/Api/V1/ImageController.php b/app/Http/Controllers/Api/V1/ImageController.php index 258dcb5f..6c72001a 100644 --- a/app/Http/Controllers/Api/V1/ImageController.php +++ b/app/Http/Controllers/Api/V1/ImageController.php @@ -40,9 +40,7 @@ class ImageController extends Controller } try { - /** @var User $user */ - $user = Auth::user(); - $image = $service->store($request, $user); + $image = $service->store($request); } catch (UploadException $e) { return $this->error($e->getMessage()); } catch (\Throwable $e) { diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index f447e29a..03bf87e6 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -8,7 +8,9 @@ use App\Enums\UserStatus; use App\Exceptions\UploadException; use App\Http\Api; use App\Models\Config; +use App\Models\Group; use App\Models\Image; +use App\Models\Strategy; use App\Models\User; use App\Services\ImageService; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; @@ -18,7 +20,6 @@ use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Routing\Controller as BaseController; use Illuminate\Support\Facades\Artisan; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Log; @@ -87,12 +88,15 @@ class Controller extends BaseController 'email' => $request->input('account.email'), 'password' => Hash::make($request->input('account.password')), ]); + $user->group_id = Group::query()->first()['id']; $user->is_adminer = true; $user->status = UserStatus::Normal; $user->email_verified_at = date('Y-m-d H:i:s'); + // 设置默认策略组的 url 为当前请求 url + Strategy::query()->where('is_guest', true)->update([ + 'configs->url' => $request->getSchemeAndHttpHost().'/i', + ]); $user->save(); - // 更新站点域名 - Config::query()->where('name', ConfigKey::AppUrl)->update(['value' => $request->getSchemeAndHttpHost()]); } catch (\Throwable $e) { @unlink(base_path('installed.lock')); return $this->error($e->getMessage()); @@ -109,9 +113,7 @@ class Controller extends BaseController public function upload(Request $request, ImageService $service): Response { try { - /** @var User $user */ - $user = Auth::user(); - $image = $service->store($request, $user); + $image = $service->store($request); } catch (UploadException $e) { return $this->error($e->getMessage()); } catch (\Throwable $e) { diff --git a/app/Http/Controllers/User/UserController.php b/app/Http/Controllers/User/UserController.php index 91aef120..4a70fd4b 100644 --- a/app/Http/Controllers/User/UserController.php +++ b/app/Http/Controllers/User/UserController.php @@ -41,7 +41,7 @@ class UserController extends Controller /** @var User $user */ $user = Auth::user(); $user->name = $request->validated('name'); - $user->url = $request->validated('url'); + $user->url = $request->validated('url') ?: ''; $user->configs = $user->configs->merge(collect($request->validated('configs'))->transform(function ($value) { return (int)$value; })); diff --git a/app/Http/Requests/Admin/GroupRequest.php b/app/Http/Requests/Admin/GroupRequest.php index 6b970b86..5f3f7e6a 100644 --- a/app/Http/Requests/Admin/GroupRequest.php +++ b/app/Http/Requests/Admin/GroupRequest.php @@ -25,6 +25,7 @@ class GroupRequest extends FormRequest return [ 'name' => 'required|between:2,30', 'is_default' => 'boolean', + 'is_guest' => 'boolean', 'configs' => 'required|array', 'configs.maximum_file_size' => 'required|numeric', 'configs.concurrent_upload_num' => 'required|integer', diff --git a/app/Http/Requests/UserSettingRequest.php b/app/Http/Requests/UserSettingRequest.php index b8154f54..9953047a 100644 --- a/app/Http/Requests/UserSettingRequest.php +++ b/app/Http/Requests/UserSettingRequest.php @@ -13,7 +13,7 @@ class UserSettingRequest extends FormRequest { return [ 'name' => 'required|between:2,20', - 'url' => 'url', + 'url' => 'nullable|url', 'password' => 'nullable|between:6,32', 'configs' => 'array', 'configs.default_album' => 'required|numeric', diff --git a/app/Models/Group.php b/app/Models/Group.php index d77b8d60..8aca3618 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -4,9 +4,7 @@ namespace App\Models; use App\Enums\ConfigKey; use App\Utils; -use Barryvdh\Debugbar\Facades\Debugbar; use Carbon\Carbon; -use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; @@ -17,6 +15,7 @@ use Illuminate\Support\Collection; * @property int $id * @property string $name * @property boolean $is_default + * @property boolean $is_guest * @property Collection $configs * @property Carbon $updated_at * @property Carbon $created_at @@ -30,12 +29,14 @@ class Group extends Model protected $fillable = [ 'name', 'is_default', + 'is_guest', 'configs', ]; protected $casts = [ 'id' => 'integer', 'is_default' => 'bool', + 'is_guest' => 'bool', 'configs' => 'collection' ]; @@ -64,6 +65,12 @@ class Group extends Model protected static function booted() { static::saving(function (self $group) { + if ($group->isDirty('is_default') && $group->is_default) { + Group::query()->where('is_default', true)->update(['is_default' => false]); + } + if ($group->isDirty('is_guest') && $group->is_guest) { + Group::query()->where('is_guest', true)->update(['is_guest' => false]); + } $group->configs = Utils::parseConfigs(self::getDefaultConfigs()->toArray(), $group->configs->toArray()); }); } @@ -75,17 +82,7 @@ class Group extends Model */ public static function getDefaultConfigs(): Collection { - return collect(config('convention.app.'.ConfigKey::Group)); - } - - /** - * 获取访客组默认配置 - * - * @return Collection - */ - public static function getGuestConfigs(): Collection - { - return Utils::config(ConfigKey::Group); + return collect(config('convention.app.group')); } public function users(): HasMany diff --git a/app/Models/Image.php b/app/Models/Image.php index 42239053..25a82250 100644 --- a/app/Models/Image.php +++ b/app/Models/Image.php @@ -194,7 +194,7 @@ class Image extends Model public function filesystem(): Filesystem { - return new Filesystem((new ImageService())->getAdapter($this->strategy->key, $this->strategy->configs)); + return new Filesystem((new ImageService())->getAdapter($this->strategy)); } public function user(): BelongsTo @@ -209,18 +209,12 @@ class Image extends Model public function group(): BelongsTo { - return $this->belongsTo(Group::class, 'group_id', 'id')->withDefault(function (Group $group) { - $group->name = '系统默认组'; - $group->configs = $group::getGuestConfigs(); - }); + return $this->belongsTo(Group::class, 'group_id', 'id'); } public function strategy(): BelongsTo { - return $this->belongsTo(Strategy::class, 'strategy_id', 'id')->withDefault(function (Strategy $strategy) { - $strategy->key = StrategyKey::Local; - $strategy->configs = collect(config('filesystems.disks.uploads')); - }); + return $this->belongsTo(Strategy::class, 'strategy_id', 'id'); } private function generateKey($length = 6): string diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 1f458441..fc20f746 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -41,17 +41,13 @@ class AppServiceProvider extends ServiceProvider if (file_exists(base_path('installed.lock'))) { // 覆盖默认配置 Config::set('app.name', Utils::config(ConfigKey::AppName)); - Config::set('app.url', Utils::config(ConfigKey::AppUrl)); Config::set('mail', array_merge(\config('mail'), Utils::config(ConfigKey::Mail)->toArray())); - // 覆盖默认组策略配置 - Config::set('filesystems.disks.uploads.url', Utils::config(ConfigKey::AppUrl).'/i'); - + $configs = Auth::check() && Auth::user()->group ? + Auth::user()->group->configs : + Group::query()->where('is_guest', true)->value('configs'); // 初始化视图中的默认数据 - View::composer('*', function (\Illuminate\View\View $view) { - $configs = Auth::check() && Auth::user()->group ? Auth::user()->group->configs : Group::getGuestConfigs(); - $view->with('groupConfigs', $configs); - }); + View::share('groupConfigs', $configs); } } } diff --git a/app/Services/ImageService.php b/app/Services/ImageService.php index f8dd555e..88e541d5 100644 --- a/app/Services/ImageService.php +++ b/app/Services/ImageService.php @@ -16,6 +16,7 @@ use App\Enums\UserStatus; use App\Enums\Watermark\FontOption; use App\Enums\Watermark\ImageOption; use App\Exceptions\UploadException; +use App\Models\Group; use App\Models\Image; use App\Models\Strategy; use App\Models\User; @@ -25,6 +26,7 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; use Illuminate\Http\UploadedFile; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; use Intervention\Image\Facades\Image as InterventionImage; @@ -40,72 +42,31 @@ class ImageService { /** * @param Request $request - * @param User|null $user * @return Image * @throws UploadException */ - public function store(Request $request, ?User $user = null): Image + public function store(Request $request): Image { $file = $request->file('file'); - if (is_null($user) && !Utils::config(ConfigKey::IsAllowGuestUpload, true)) { + if (Auth::guest() && !Utils::config(ConfigKey::IsAllowGuestUpload, true)) { throw new UploadException('管理员关闭了游客上传'); } $img = InterventionImage::make($file); $image = new Image(); + /** @var User|null $user */ + $user = $request->user(); + + /** @var Group $group */ + $group = ! is_null($user) ? $user->group : Group::query()->where('is_guest', true)->first(); // 组配置 - $configs = Utils::config(ConfigKey::Group); - // 默认使用本地储存策略 - $disk = collect([ - 'driver' => StrategyKey::Local, - 'configs' => collect([LocalOption::Root => config('filesystems.disks.uploads.root')]), - ]); - - // 图片默认权限 - $image->permission = ImagePermission::Private; - - if (!is_null($user)) { - if (Utils::config(ConfigKey::IsUserNeedVerify) && !$user->email_verified_at) { - throw new UploadException('账户未验证'); - } - - if ($user->status !== UserStatus::Normal) { - throw new UploadException('账号状态异常'); - } - - // 如果该用户有角色组,覆盖默认组、上传策略配置 - if ($user->group) { - $image->group_id = $user->group_id; - $configs = $user->group->configs; - // 获取策略列表,根据用户所选的策略上传 - $strategies = $user->group->strategies()->get(); - if ($strategies->isNotEmpty()) { - // 是否指定了默认的策略 - $defaultStrategyId = $user->configs->get(UserConfigKey::DefaultStrategy, 0); - /** @var Strategy $strategy $disk */ - $strategy = $strategies->find($defaultStrategyId, $strategies->first()); - $disk = collect(['driver' => $strategy->key, 'configs' => $strategy->configs]); - $image->strategy_id = $strategy->id; - } - } - - if ($file->getSize() / 1024 + $user->images()->sum('size') > $user->capacity) { - throw new UploadException('储存空间不足'); - } - - $image->user_id = $user->id; - - // 图片保存至默认相册(若有) - if ($albumId = $user->configs->get(UserConfigKey::DefaultAlbum)) { - if ($user->albums()->where('id', $albumId)->exists()) { - $image->album_id = $albumId; - } - } - - // 用户设置的图片默认权限 - $image->permission = $user->configs->get(UserConfigKey::DefaultPermission, ImagePermission::Private); + $configs = $group->configs; + // 储存策略 + $strategies = $group->strategies()->get(); + if ($strategies->isEmpty()) { + throw new UploadException('没有可用的储存,请联系管理员。'); } if (!in_array($file->extension(), $configs->get(GroupConfigKey::AcceptedFileSuffixes))) { @@ -116,8 +77,47 @@ class ImageService throw new UploadException("图片大小超出限制"); } + // 图片所属组 + $image->group_id = $group->id; + // 图片默认权限 + $image->permission = ImagePermission::Private; + + // 默认储存策略 + if (is_null($user)) { + // 游客随机一个储存,TODO 适配前端切换 + $strategy = $strategies->random(1)->first(); + $image->strategy_id = $strategy->id; + } else { + /** @var Strategy $strategy */ + $strategy = $strategies->find($user->configs->get(UserConfigKey::DefaultStrategy, 0), $strategies->first()); + + if (Utils::config(ConfigKey::IsUserNeedVerify) && ! $user->email_verified_at) { + throw new UploadException('账户未验证'); + } + + if ($user->status !== UserStatus::Normal) { + throw new UploadException('账号状态异常'); + } + + if ($file->getSize() / 1024 + $user->images()->sum('size') > $user->capacity) { + throw new UploadException('储存空间不足'); + } + + // 图片保存至默认相册(若有) + if ($albumId = $user->configs->get(UserConfigKey::DefaultAlbum)) { + if ($user->albums()->where('id', $albumId)->exists()) { + $image->album_id = $albumId; + } + } + + $image->strategy_id = $strategy->id; + $image->user_id = $user->id; + // 用户设置的图片默认权限 + $image->permission = $user->configs->get(UserConfigKey::DefaultPermission, ImagePermission::Private); + } + // 上传频率限制 - $this->rateLimiter($configs, $request, $user); + $this->rateLimiter($configs, $request); $filename = $this->replacePathname( $configs->get(GroupConfigKey::PathNamingRule).'/'.$configs->get(GroupConfigKey::FileNamingRule), $file, @@ -139,7 +139,7 @@ class ImageService 'uploaded_ip' => $request->ip(), ]); - $filesystem = new Filesystem($this->getAdapter($disk->get('driver'), $disk->get('configs'))); + $filesystem = new Filesystem($this->getAdapter($strategy)); // 检测该策略是否存在该图片,有则只创建记录不保存文件 /** @var Image $existing */ $existing = Image::query()->when($image->strategy_id, function (Builder $builder, $id) { @@ -157,7 +157,16 @@ class ImageService $image->fill($existing->only('path', 'name')); } - DB::transaction(function () use ($image, $user, $filesystem, $existing) { + $updateNum = function ($method) use ($user, $image) { + if (! is_null($user)) { + $user->{$method}('image_num'); + } + if (! is_null($image->album)) { + $image->album->{$method}('image_num'); + } + }; + + DB::transaction(function () use ($image, $user, $filesystem, $existing, $updateNum) { if (!$image->save()) { // 删除文件 if (is_null($existing)) { @@ -165,12 +174,7 @@ class ImageService } throw new UploadException('图片保存失败'); } - if (!is_null($user)) { - $user->increment('image_num'); - } - if (!is_null($image->album)) { - $image->album->increment('image_num'); - } + $updateNum('increment'); }, 2); // 图片检测 @@ -180,6 +184,7 @@ class ImageService // 标记 or 删除 if ($configs->get(GroupConfigKey::ScannedAction) === 'delete') { $image->delete(); + DB::transaction(fn () => $updateNum('decrement')); throw new UploadException('图片涉嫌违规,禁止上传。'); } else { $image->is_unhealthy = true; @@ -191,10 +196,11 @@ class ImageService return $image; } - public function getAdapter(int $disk, Collection $configs): FilesystemAdapter + public function getAdapter(Strategy $strategy): FilesystemAdapter { - return match ($disk) { - StrategyKey::Local => new LocalFilesystemAdapter($configs->get('root') ?: config('filesystems.disks.uploads.root')), + $configs = $strategy->configs; + return match ($strategy->key) { + StrategyKey::Local => new LocalFilesystemAdapter($configs->get('root')), StrategyKey::Kodo => new QiniuAdapter( accessKey: $configs->get(KodoOption::AccessKey), secretKey: $configs->get(KodoOption::SecretKey), @@ -207,8 +213,10 @@ class ImageService /** * @throws UploadException */ - protected function rateLimiter(Collection $configs, Request $request, ?User $user = null) + protected function rateLimiter(Collection $configs, Request $request) { + /** @var User|null $user */ + $user = $request->user(); $carbon = Carbon::now(); $array = [ 'minute' => ['key' => GroupConfigKey::LimitPerMinute, 'str' => '分钟'], @@ -222,7 +230,7 @@ class ImageService $value = $configs->get($item['key'], 0); $count = Image::query()->whereBetween('created_at', [ $carbon->parse("-1 {$key}"), $carbon, - ])->when(!is_null($user), function (Builder $builder) use ($user) { + ])->when(! is_null($user), function (Builder $builder) use ($user) { $builder->where('user_id', $user->id); }, function (Builder $builder) use ($request) { $builder->where('uploaded_ip', $request->ip())->whereNull('user_id'); diff --git a/composer.lock b/composer.lock index a7907e85..dc5c4610 100644 --- a/composer.lock +++ b/composer.lock @@ -334,16 +334,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.209.30", + "version": "3.211.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "54c1e491b8de74360bbe94d727706db384c8d9a8" + "reference": "be209936fc1c70bb2e842cad2f3550ebb12d4eb8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/54c1e491b8de74360bbe94d727706db384c8d9a8", - "reference": "54c1e491b8de74360bbe94d727706db384c8d9a8", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/be209936fc1c70bb2e842cad2f3550ebb12d4eb8", + "reference": "be209936fc1c70bb2e842cad2f3550ebb12d4eb8", "shasum": "", "mirrors": [ { @@ -425,9 +425,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.209.30" + "source": "https://github.com/aws/aws-sdk-php/tree/3.211.0" }, - "time": "2022-02-23T19:14:31+00:00" + "time": "2022-02-28T19:50:29+00:00" }, { "name": "brick/math", @@ -1170,16 +1170,16 @@ }, { "name": "doctrine/lexer", - "version": "1.2.2", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c" + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", - "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", "shasum": "", "mirrors": [ { @@ -1193,7 +1193,7 @@ }, "require-dev": { "doctrine/coding-standard": "^9.0", - "phpstan/phpstan": "1.3", + "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "vimeo/psalm": "^4.11" }, @@ -1232,7 +1232,7 @@ ], "support": { "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/1.2.2" + "source": "https://github.com/doctrine/lexer/tree/1.2.3" }, "funding": [ { @@ -1248,7 +1248,7 @@ "type": "tidelift" } ], - "time": "2022-01-12T08:27:12+00:00" + "time": "2022-02-28T11:07:21+00:00" }, { "name": "dragonmantank/cron-expression", @@ -4499,16 +4499,16 @@ }, { "name": "psy/psysh", - "version": "v0.11.1", + "version": "v0.11.2", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "570292577277f06f590635381a7f761a6cf4f026" + "reference": "7f7da640d68b9c9fec819caae7c744a213df6514" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/570292577277f06f590635381a7f761a6cf4f026", - "reference": "570292577277f06f590635381a7f761a6cf4f026", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/7f7da640d68b9c9fec819caae7c744a213df6514", + "reference": "7f7da640d68b9c9fec819caae7c744a213df6514", "shasum": "", "mirrors": [ { @@ -4525,6 +4525,9 @@ "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4", "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4" }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, "require-dev": { "bamarni/composer-bin-plugin": "^1.2", "hoa/console": "3.17.05.02" @@ -4574,9 +4577,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.11.1" + "source": "https://github.com/bobthecow/psysh/tree/v0.11.2" }, - "time": "2022-01-03T13:58:38+00:00" + "time": "2022-02-28T15:28:54+00:00" }, { "name": "qiniu/php-sdk", @@ -4846,12 +4849,12 @@ } }, "autoload": { - "psr-4": { - "Ramsey\\Uuid\\": "src/" - }, "files": [ "src/functions.php" - ] + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -9127,16 +9130,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.13", + "version": "9.2.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "deac8540cb7bd40b2b8cfa679b76202834fd04e8" + "reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/deac8540cb7bd40b2b8cfa679b76202834fd04e8", - "reference": "deac8540cb7bd40b2b8cfa679b76202834fd04e8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f4d60b6afe5546421462b76cd4e633ebc364ab4", + "reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4", "shasum": "", "mirrors": [ { @@ -9198,7 +9201,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.13" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.14" }, "funding": [ { @@ -9206,7 +9209,7 @@ "type": "github" } ], - "time": "2022-02-23T17:02:38+00:00" + "time": "2022-02-28T12:38:02+00:00" }, { "name": "phpunit/php-file-iterator", @@ -10712,16 +10715,16 @@ }, { "name": "spatie/flare-client-php", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/spatie/flare-client-php.git", - "reference": "9b54db8774b6bd7ad7cfa4c035820ef63ea1a75c" + "reference": "edf253c68fba62cdb29ad6b48e211e29691dcee8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/9b54db8774b6bd7ad7cfa4c035820ef63ea1a75c", - "reference": "9b54db8774b6bd7ad7cfa4c035820ef63ea1a75c", + "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/edf253c68fba62cdb29ad6b48e211e29691dcee8", + "reference": "edf253c68fba62cdb29ad6b48e211e29691dcee8", "shasum": "", "mirrors": [ { @@ -10770,7 +10773,7 @@ ], "support": { "issues": "https://github.com/spatie/flare-client-php/issues", - "source": "https://github.com/spatie/flare-client-php/tree/1.0.3" + "source": "https://github.com/spatie/flare-client-php/tree/1.0.4" }, "funding": [ { @@ -10778,7 +10781,7 @@ "type": "github" } ], - "time": "2022-02-25T11:05:23+00:00" + "time": "2022-02-28T15:04:23+00:00" }, { "name": "spatie/ignition", diff --git a/config/convention.php b/config/convention.php index a874180b..ebf202e7 100644 --- a/config/convention.php +++ b/config/convention.php @@ -12,7 +12,6 @@ use App\Enums\Watermark\ImageOption; return [ 'app' => [ ConfigKey::AppName => 'Lsky Pro', - ConfigKey::AppUrl => env('APP_URL'), ConfigKey::AppVersion => '2.0', ConfigKey::SiteKeywords => 'Lsky Pro,lsky,兰空图床', ConfigKey::SiteDescription => 'Lsky Pro, Your photo album on the cloud.', diff --git a/database/migrations/2014_10_10_000000_create_groups_table.php b/database/migrations/2014_10_10_000000_create_groups_table.php index fd6b33c3..eba177da 100644 --- a/database/migrations/2014_10_10_000000_create_groups_table.php +++ b/database/migrations/2014_10_10_000000_create_groups_table.php @@ -21,6 +21,7 @@ return new class extends Migration $table->id(); $table->string('name', 64)->comment('角色组名称'); $table->boolean('is_default')->default(false)->comment('是否默认'); + $table->boolean('is_guest')->default(false)->comment('是否为游客组'); $table->json('configs')->comment('组配置'); $table->timestamps(); }); diff --git a/database/seeders/InstallSeeder.php b/database/seeders/InstallSeeder.php index 2e18bdf2..d846a041 100644 --- a/database/seeders/InstallSeeder.php +++ b/database/seeders/InstallSeeder.php @@ -2,6 +2,9 @@ namespace Database\Seeders; +use App\Enums\ConfigKey; +use App\Enums\StrategyKey; +use App\Models\Group; use Illuminate\Database\Seeder; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; @@ -16,7 +19,9 @@ class InstallSeeder extends Seeder public function run() { $date = Carbon::now()->format('Y-m-d H:i:s'); - $array = collect(config('convention.app'))->transform(function ($value, $key) use ($date) { + $array = collect(config('convention.app'))->except([ + ConfigKey::Group, + ])->transform(function ($value, $key) use ($date) { return [ 'name' => $key, 'value' => is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value, @@ -24,6 +29,23 @@ class InstallSeeder extends Seeder 'created_at' => $date, ]; })->values()->toArray(); - DB::table('configs')->insert($array); + DB::transaction(function () use ($array) { + DB::table('configs')->insert($array); + // 创建默认组和默认策略 + /** @var Group $group */ + $group = Group::query()->create([ + 'name' => '系统默认组&游客组', + 'is_default' => true, + 'is_guest' => true, + 'configs' => config('convention.app.group'), + ]); + // 创建默认策略 + $group->strategies()->create([ + 'key' => StrategyKey::Local, + 'name' => '默认本地策略', + 'intro' => '系统默认的本地策略', + 'configs' => config('filesystems.disks.uploads'), + ]); + }); } } diff --git a/resources/views/admin/group/add.blade.php b/resources/views/admin/group/add.blade.php index b27e7108..7b0fbe59 100644 --- a/resources/views/admin/group/add.blade.php +++ b/resources/views/admin/group/add.blade.php @@ -5,7 +5,7 @@ @include('admin.group.tips')

- 角色组设置默认以后新用户注册会归属该角色组,系统可以设置多个默认角色组,出现多个默认组,新用户将会以随机的方式归属某一个默认角色组。 + 角色组设置默认以后新用户注册会归属该角色组,系统只能设置一个默认角色组。设置为游客组后,未登录用户将会受游客组控制。

@@ -78,11 +78,17 @@
- +
+
+ + + +
+
@foreach($default->get('accepted_file_suffixes') as $extension) diff --git a/resources/views/admin/group/edit.blade.php b/resources/views/admin/group/edit.blade.php index 6310aa65..468b60ed 100644 --- a/resources/views/admin/group/edit.blade.php +++ b/resources/views/admin/group/edit.blade.php @@ -4,12 +4,6 @@
@include('admin.group.tips') - @if($group->id == 0) -

- 当前编辑的是系统默认组,所有访客、以及未被设置角色组的用户上传的图片将会受这个角色组控制。默认组的图片访问域名为站点域名,域名可以在系统设置中更改。 -

- @endif -
-
+
- @if($group->id == 0) - - - @else - - @endif +
@@ -84,13 +73,17 @@
- @if($group->id)
- +
- @endif + +
+ + + +
diff --git a/resources/views/admin/group/index.blade.php b/resources/views/admin/group/index.blade.php index 971bc442..2d07bed3 100644 --- a/resources/views/admin/group/index.blade.php +++ b/resources/views/admin/group/index.blade.php @@ -9,32 +9,7 @@
- - - - - 系统默认组 - - - - - - - - - - - - - - - - - - - - - - - 编辑 - - + @foreach($groups as $group) {{ $group->id }} @@ -44,6 +19,11 @@ + + + + + @@ -63,13 +43,15 @@ {{ $group->strategies_count }} 编辑 + @if(! $group->is_default && ! $group->is_guest) 删除 + @endif @endforeach @if($groups->isEmpty()) - + @else
{{ $groups->links() }} diff --git a/resources/views/admin/setting/index.blade.php b/resources/views/admin/setting/index.blade.php index 395b91af..46253a85 100644 --- a/resources/views/admin/setting/index.blade.php +++ b/resources/views/admin/setting/index.blade.php @@ -13,10 +13,6 @@
-
- - -
{{ $configs['site_keywords'] }} diff --git a/resources/views/admin/strategy/add.blade.php b/resources/views/admin/strategy/add.blade.php index 4df852c0..026750d6 100644 --- a/resources/views/admin/strategy/add.blade.php +++ b/resources/views/admin/strategy/add.blade.php @@ -2,6 +2,8 @@
+ @include('admin.strategy.tips') +
diff --git a/resources/views/admin/strategy/edit.blade.php b/resources/views/admin/strategy/edit.blade.php index 66ab402a..0e869df6 100644 --- a/resources/views/admin/strategy/edit.blade.php +++ b/resources/views/admin/strategy/edit.blade.php @@ -2,6 +2,8 @@
+ @include('admin.strategy.tips') +
diff --git a/resources/views/admin/strategy/tips.blade.php b/resources/views/admin/strategy/tips.blade.php new file mode 100644 index 00000000..d135a3bb --- /dev/null +++ b/resources/views/admin/strategy/tips.blade.php @@ -0,0 +1,3 @@ +

+ 一个策略可以关联多个角色组,一个角色组也可以关联多个策略,注意,如果某个组未设置储存策略,那么该角色组下的用户将无法上传图片。 +

diff --git a/resources/views/common/api.blade.php b/resources/views/common/api.blade.php index 5edc54c5..3cc71f4b 100644 --- a/resources/views/common/api.blade.php +++ b/resources/views/common/api.blade.php @@ -6,7 +6,7 @@

接口URL

- {{ \App\Utils::config(\App\Enums\ConfigKey::AppUrl) }}/api/v1 + {{ request()->getSchemeAndHttpHost() }}/api/v1
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 47a774a4..af068d28 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -46,5 +46,15 @@
+ @stack('scripts')