角色组增删改查

This commit is contained in:
Wisp X 2022-01-23 15:48:45 +08:00
parent fbd0a59938
commit 2ee532b313
11 changed files with 188 additions and 70 deletions

View File

@ -1,15 +1,19 @@
<?php
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\View\View;
class GroupController extends Controller
@ -33,7 +37,7 @@ class GroupController extends Controller
'scanAliyunScenes' => [
'porn' => '智能鉴黄',
'terrorism' => '暴恐涉政',
'ad' => '暴恐涉政',
'ad' => '图文违规',
'qrcode' => '二维码',
'live' => '不良场景',
'logo' => 'Logo',
@ -70,16 +74,37 @@ class GroupController extends Controller
public function create(GroupRequest $request): Response
{
return $this->success('success', $request->validated());
$group = new Group();
$group->fill($request->validated());
$group->save();
return $this->success('创建成功');
}
public function update(GroupRequest $request): Response
{
return $this->success('success', $request->validated());
if ($request->route('id') == 0) {
Config::query()->where('name', ConfigKey::GroupConfigs)->update([
'value' => collect(Group::parseConfigs($request->validated('configs'))),
]);
// 删除配置缓存
Cache::forget('configs');
} else {
/** @var Group $group */
$group = Group::query()->findOrFail($request->route('id'));
$group->fill($request->validated());
if (!$group->save()) {
return $this->error('保存失败');
}
}
return $this->success('保存成功');
}
public function delete(Request $request): Response
{
return $this->success('success', $request->all());
if ($group = Group::query()->find($request->route('id'))) {
$group->delete();
}
return $this->success('删除成功');
}
}

View File

@ -1,10 +0,0 @@
<?php
namespace App\Mappers;
use JsonMapper\Middleware\Attributes\MapFrom;
class GroupConfig
{
public int $maximumFileSize = 5120;
}

View File

@ -3,7 +3,6 @@
namespace App\Models;
use App\Enums\ConfigKey;
use App\Enums\GroupConfigKey;
use App\Utils;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -34,7 +33,7 @@ class Group extends Model
protected $casts = [
'is_default' => 'bool',
'configs' => 'collection',
'configs' => 'collection'
];
/**
@ -47,11 +46,33 @@ class Group extends Model
return Utils::config(ConfigKey::GroupConfigs);
}
protected static function booted()
/**
* 格式化配置,设置默认配置以及将字符串数字转换为数字
*
* @param $configs
* @return array
*/
public static function parseConfigs($configs): array
{
static::creating(function (self $group) {
$group->configs = config('convention.app.'.ConfigKey::GroupConfigs)->merge($group->configs ?: []);
if ($configs instanceof Collection) {
$configs = $configs->toArray();
}
$array = array_replace_recursive(config('convention.app.'.ConfigKey::GroupConfigs), Utils::filter($configs));
array_walk_recursive($array, function (&$item) {
if (ctype_digit($item)) {
$item += 0;
}
if (is_null($item)) {
unset($item);
}
});
return $array;
}
public function setConfigsAttribute($value)
{
$this->attributes['configs'] = json_encode(self::parseConfigs($value), JSON_UNESCAPED_UNICODE);
}
public function users(): HasMany

View File

@ -12,8 +12,8 @@ class Utils
/**
* 获取系统配置,获取全部配置时将返回
*
* @param string $name
* @param mixed|null $default
* @param string $name
* @param mixed|null $default
*
* @return mixed
*/
@ -47,7 +47,7 @@ class Utils
/**
* 转换字段单位
*
* @param int|float $size 字节b
* @param int|float $size 字节b
* @return string
*/
public static function formatSize(int|float $size): string
@ -63,6 +63,24 @@ class Utils
$i = $n - 1;
}
return sprintf("%.2f", $size / pow($base, $i)) . ' ' . $unit[$i] . 'B';
return sprintf("%.2f", $size / pow($base, $i)).' '.$unit[$i].'B';
}
/**
* 递归过滤数组元素
*
* @param array $array
* @param callable|null $callback
* @param int $mode
* @return array
*/
public static function filter(array $array, callable $callback = null, int $mode = 0): array
{
foreach ($array as &$value) {
if (is_array($value)) {
$value = self::filter($value);
}
}
return array_filter($array, $callback, $mode);
}
}

61
composer.lock generated
View File

@ -1580,16 +1580,16 @@
},
{
"name": "league/commonmark",
"version": "2.1.1",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "17d2b9cb5161a2ea1a8dd30e6991d668e503fb9d"
"reference": "c5aadcc15548629787d02b86a7afef03b46271b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/17d2b9cb5161a2ea1a8dd30e6991d668e503fb9d",
"reference": "17d2b9cb5161a2ea1a8dd30e6991d668e503fb9d",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c5aadcc15548629787d02b86a7afef03b46271b5",
"reference": "c5aadcc15548629787d02b86a7afef03b46271b5",
"shasum": "",
"mirrors": [
{
@ -1603,6 +1603,7 @@
"league/config": "^1.1.1",
"php": "^7.4 || ^8.0",
"psr/event-dispatcher": "^1.0",
"symfony/deprecation-contracts": "^v2.1 || ^3.0",
"symfony/polyfill-php80": "^1.15"
},
"require-dev": {
@ -1628,7 +1629,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.2-dev"
"dev-main": "2.3-dev"
}
},
"autoload": {
@ -1685,7 +1686,7 @@
"type": "tidelift"
}
],
"time": "2022-01-02T18:25:06+00:00"
"time": "2022-01-22T14:06:22+00:00"
},
{
"name": "league/config",
@ -2780,16 +2781,16 @@
},
{
"name": "psr/log",
"version": "1.1.4",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
"shasum": "",
"mirrors": [
{
@ -2799,17 +2800,17 @@
]
},
"require": {
"php": ">=5.3.0"
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
"dev-master": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
"Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@ -2830,22 +2831,22 @@
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/1.1.4"
"source": "https://github.com/php-fig/log/tree/3.0.0"
},
"time": "2021-05-03T11:20:27+00:00"
"time": "2021-07-14T16:46:02+00:00"
},
{
"name": "psr/simple-cache",
"version": "1.0.1",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/simple-cache.git",
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865",
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865",
"shasum": "",
"mirrors": [
{
@ -2855,12 +2856,12 @@
]
},
"require": {
"php": ">=5.3.0"
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "3.0.x-dev"
}
},
"autoload": {
@ -2875,7 +2876,7 @@
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interfaces for simple caching",
@ -2887,9 +2888,9 @@
"simple-cache"
],
"support": {
"source": "https://github.com/php-fig/simple-cache/tree/master"
"source": "https://github.com/php-fig/simple-cache/tree/3.0.0"
},
"time": "2017-10-23T01:57:42+00:00"
"time": "2021-10-29T13:26:27+00:00"
},
{
"name": "psy/psysh",
@ -7338,16 +7339,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.5.11",
"version": "9.5.12",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "2406855036db1102126125537adb1406f7242fdd"
"reference": "93d4bf4c37aec6384bb9e5d390d9049a463a7256"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2406855036db1102126125537adb1406f7242fdd",
"reference": "2406855036db1102126125537adb1406f7242fdd",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/93d4bf4c37aec6384bb9e5d390d9049a463a7256",
"reference": "93d4bf4c37aec6384bb9e5d390d9049a463a7256",
"shasum": "",
"mirrors": [
{
@ -7431,7 +7432,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.11"
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.12"
},
"funding": [
{
@ -7443,7 +7444,7 @@
"type": "github"
}
],
"time": "2021-12-25T07:07:57+00:00"
"time": "2022-01-21T05:54:47+00:00"
},
{
"name": "sebastian/cli-parser",

View File

@ -15,11 +15,11 @@ return [
ConfigKey::SiteKeywords => 'Lsky Pro,lsky,兰空图床',
ConfigKey::SiteDescription => 'Lsky Pro, Your photo album on the cloud.',
ConfigKey::IcpNo => '',
ConfigKey::IsEnableRegistration => true,
ConfigKey::IsEnableGallery => true,
ConfigKey::IsAllowGuestUpload => true,
ConfigKey::IsEnableRegistration => 1,
ConfigKey::IsEnableGallery => 1,
ConfigKey::IsAllowGuestUpload => 1,
ConfigKey::UserInitialCapacity => 512000,
ConfigKey::IsUserNeedVerify => true,
ConfigKey::IsUserNeedVerify => 1,
ConfigKey::MailConfigs => [
'default' => 'smtp',
'mailers' => [
@ -35,9 +35,9 @@ return [
ConfigKey::GroupConfigs => [
GroupConfigKey::MaximumFileSize => 5120,
GroupConfigKey::ConcurrentUploadNum => 3,
GroupConfigKey::IsEnableScan => false,
GroupConfigKey::IsEnableWatermark => false,
GroupConfigKey::IsEnableOriginalProtection => false,
GroupConfigKey::IsEnableScan => 0,
GroupConfigKey::IsEnableWatermark => 0,
GroupConfigKey::IsEnableOriginalProtection => 0,
GroupConfigKey::ScannedAction => 'mark', // in mark or delete
GroupConfigKey::ScanConfigs => [
'driver' => 'aliyun',

View File

@ -2,6 +2,10 @@
<div class="my-6 md:my-10">
@include('admin.group.tips')
<p class="bg-blue-500 p-2 mb-2 rounded text-sm text-white">
<i class="fas fa-exclamation-circle"></i> 角色组设置默认以后新用户注册会归属该角色组,系统可以设置多个默认角色组,出现多个默认组,新用户将会以随机的方式归属某一个默认角色组。
</p>
<div class="mt-5 md:mt-0 md:col-span-2">
<ul id="tabs" class="flex space-x-2 text-sm">
<li class="group">
@ -275,6 +279,9 @@
axios.post(this.action, $(this).serialize()).then(response => {
if (response.data.status) {
toastr.success(response.data.message);
setTimeout(function () {
window.location.href = '{{ route('admin.groups') }}';
}, 3000);
} else {
toastr.error(response.data.message);
}

View File

@ -2,6 +2,12 @@
<div class="my-6 md:my-10">
@include('admin.group.tips')
@if($group->id == 0)
<p class="bg-blue-500 p-2 mb-2 rounded text-sm text-white">
<i class="fas fa-exclamation-circle"></i> 当前编辑的是系统默认组,所有访客、以及未被设置角色组的用户上传的图片将会受这个角色组控制。
</p>
@endif
<div class="mt-5 md:mt-0 md:col-span-2">
<ul id="tabs" class="flex space-x-2 text-sm">
<li class="group">
@ -132,7 +138,7 @@
<div class="col-span-6 sm:col-span-3 mb-4">
<x-fieldset title="审核场景">
@foreach($scanAliyunScenes as $key => $scene)
<x-fieldset-checkbox id="configs[scan_configs][drivers][aliyun][scenes][]_{{ $key }}" name="configs[scan_configs][drivers][aliyun][scenes][]" value="{{ $key }}" :checked="in_array($scene, $group->configs['scan_configs']['drivers']['aliyun']['scenes'])">{{ $scene }}</x-fieldset-checkbox>
<x-fieldset-checkbox id="configs[scan_configs][drivers][aliyun][scenes][]_{{ $key }}" name="configs[scan_configs][drivers][aliyun][scenes][]" value="{{ $key }}" :checked="in_array($key, $group->configs['scan_configs']['drivers']['aliyun']['scenes'])">{{ $scene }}</x-fieldset-checkbox>
@endforeach
</x-fieldset>
</div>
@ -247,7 +253,7 @@
</div>
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<x-button type="button" class="bg-gray-500" onclick="history.go(-1)">取消</x-button>
<x-button>确认创建</x-button>
<x-button>确认保存</x-button>
</div>
</div>
</form>

View File

@ -9,11 +9,26 @@
</form>
</div>
<x-table :columns="['ID', '名称', '是否默认', '用户数量', '策略数量', '操作']">
<x-table :columns="['ID', '名称', '是否默认', '图片审核', '原图保护', '水印' ,'用户数量', '策略数量', '操作']">
<tr data-id="0">
<td class="px-6 py-4 whitespace-nowrap">-</td>
<td class="px-6 py-4 whitespace-nowrap name">系统默认组</td>
<td class="px-6 py-4 whitespace-nowrap">-</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ $default['is_enable_scan'] ? 'text-green-800' : 'text-red-800' }}">
<i class="text-lg fas fa-{{ $default['is_enable_scan'] ? 'check-circle' : 'times-circle' }}"></i>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ $default['is_enable_original_protection'] ? 'text-green-800' : 'text-red-800' }}">
<i class="text-lg fas fa-{{ $default['is_enable_original_protection'] ? 'check-circle' : 'times-circle' }}"></i>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ $default['is_enable_watermark'] ? 'text-green-800' : 'text-red-800' }}">
<i class="text-lg fas fa-{{ $default['is_enable_watermark'] ? 'check-circle' : 'times-circle' }}"></i>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">-</td>
<td class="px-6 py-4 whitespace-nowrap">-</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium space-x-2">
@ -29,6 +44,21 @@
<i class="text-lg fas fa-{{ $group->is_default ? 'check-circle' : 'times-circle' }}"></i>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ $group->configs['is_enable_scan'] ? 'text-green-800' : 'text-red-800' }}">
<i class="text-lg fas fa-{{ $group->configs['is_enable_scan'] ? 'check-circle' : 'times-circle' }}"></i>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ $group->configs['is_enable_original_protection'] ? 'text-green-800' : 'text-red-800' }}">
<i class="text-lg fas fa-{{ $group->configs['is_enable_original_protection'] ? 'check-circle' : 'times-circle' }}"></i>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ $group->configs['is_enable_watermark'] ? 'text-green-800' : 'text-red-800' }}">
<i class="text-lg fas fa-{{ $group->configs['is_enable_watermark'] ? 'check-circle' : 'times-circle' }}"></i>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">{{ $group->users_count }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ $group->strategies_count }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium space-x-2">
@ -61,7 +91,7 @@
}).then((result) => {
if (result.isConfirmed) {
let id = $(this).closest('tr').data('id');
axios.delete(`/groups/${id}`).then(response => {
axios.delete(`/admin/groups/${id}`).then(response => {
if (response.data.status) {
history.go(0);
} else {

View File

@ -3,6 +3,6 @@
<i class="fas fa-exclamation-circle"></i> 当前系统监测到运行环境关闭了 HTTP 上传文件权限(file_uploads=off),请更改 PHP 此项配置,否则无法上传文件。
</p>
@endif
<p class="bg-yellow-500 p-2 mb-4 rounded text-sm text-white">
<p class="bg-yellow-500 p-2 mb-2 rounded text-sm text-white">
<i class="fas fa-exclamation-circle"></i> 系统运行环境允许上传大小的最大值为 {{ ini_get('upload_max_filesize') }},最大 POST 数据大小为 {{ ini_get('post_max_size') }},上传文件大小不得超过这两项配置值。
</p>

View File

@ -10,11 +10,6 @@ use Tests\TestCase;
class UtilTest extends TestCase
{
/**
* A basic unit test example.
*
* @return void
*/
public function test_config()
{
Cache::forget('configs');
@ -39,4 +34,29 @@ class UtilTest extends TestCase
$this->assertTrue(true);
}
}
public function test_array_filter_recursive()
{
$array = Utils::filter([
'name' => 'Lsky',
'age' => null,
'configs' => [
'one' => null,
'two' => 1
]
]);
if (! array_key_exists('age', $array)) {
$this->assertTrue(true);
}
if (! array_key_exists('one', $array['configs'])) {
$this->assertTrue(true);
}
if (! array_key_exists('two', $array['configs'])) {
$this->assertTrue(true);
}
}
}