1
0
Fork 0

UserService 添加表单验证

main
panliang 2024-10-31 11:29:57 +08:00
parent 83cf255f98
commit b6a620e935
8 changed files with 87 additions and 7 deletions

View File

@ -51,3 +51,7 @@ public function filteredResults()
return \Slowlyo\OwlAdmin\Support\Cores\AdminPipeline::handle(static::class, $this->amisSchema); return \Slowlyo\OwlAdmin\Support\Cores\AdminPipeline::handle(static::class, $this->amisSchema);
} }
``` ```
## TODO
- 表单验证: 服务端返回 `errors` 不生效, https://aisuda.bce.baidu.com/amis/zh-CN/components/form/formitem#%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%A0%A1%E9%AA%8C

View File

@ -22,13 +22,15 @@ class UserController extends AdminController
->headerToolbar([ ->headerToolbar([
$this->createButton('drawer', 'lg')->permission('admin.users.create'), $this->createButton('drawer', 'lg')->permission('admin.users.create'),
...$this->baseHeaderToolBar(), ...$this->baseHeaderToolBar(),
$this->exportAction(),
]) ])
->bulkActions([ ->bulkActions([
$this->bulkDeleteButton()->permission('admin.users.delete') $this->bulkDeleteButton()->permission('admin.users.delete')
]) ])
->filter($this->baseFilter()->body([ ->filter($this->baseFilter()->body([
amis()->GroupControl()->mode('horizontal')->body([ amis()->GroupControl()->mode('horizontal')->body([
amis()->TextControl()->name('search')->label(__('admin.search'))->columnRatio(3)->clearable(), amis()->TextControl()->name('search')->label(__('admin.search'))->placeholder(__('users.phone').'/'.__('users.name'))->columnRatio(3)->clearable(),
amis()->DateRangeControl()->name('created_range')->label(__('users.created_at'))->columnRatio(3)->clearable(),
]) ])
])) ]))
->columns([ ->columns([
@ -65,4 +67,15 @@ class UserController extends AdminController
['label' => __('users.created_at'), 'content' => '${created_at}'], ['label' => __('users.created_at'), 'content' => '${created_at}'],
])); ]));
} }
protected function exportMap($row)
{
return [
__('admin.id') => $row['id'],
__('users.avatar') => $row['avatar'],
__('users.phone') => $row['phone'],
__('users.name') => $row['name'],
__('users.created_at') => $row['created_at'],
];
}
} }

View File

@ -0,0 +1,29 @@
<?php
namespace App\Exceptions;
use Illuminate\Support\Arr;
use Slowlyo\OwlAdmin\Admin;
use Illuminate\Support\MessageBag;
use Slowlyo\OwlAdmin\Exceptions\AdminException;
class AdminValidationException extends AdminException
{
protected $errors;
public function __construct(MessageBag $error)
{
parent::__construct($error->first());
$errors = [];
foreach($error->messages() as $key => $messages) {
$errors[$key] = Arr::first($messages);
}
$this->errors = $errors;
}
public function render()
{
return Admin::response()->additional(['errors' => $this->errors])->fail($this->getMessage());
}
}

View File

@ -2,6 +2,7 @@
namespace App\ModelFilters; namespace App\ModelFilters;
use Carbon\Carbon;
use EloquentFilter\ModelFilter; use EloquentFilter\ModelFilter;
class UserFilter extends ModelFilter class UserFilter extends ModelFilter
@ -19,4 +20,16 @@ class UserFilter extends ModelFilter
$str = '%'.$key.'%'; $str = '%'.$key.'%';
return $this->where(fn($q) => $q->where('phone', 'like', $str)->orWhere('name', 'like', $str)); return $this->where(fn($q) => $q->where('phone', 'like', $str)->orWhere('name', 'like', $str));
} }
public function createdRange($key)
{
$keys = explode(',', $key);
$start = data_get($keys, 0);
$end = data_get($keys, 1);
if ($start && $end) {
$start = Carbon::createFromTimestamp($start);
$end = Carbon::createFromTimestamp($end);
return $this->whereBetween('created_at', [$start, $end]);
}
}
} }

View File

@ -2,6 +2,7 @@
namespace App\Providers; namespace App\Providers;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider class AppServiceProvider extends ServiceProvider
@ -19,6 +20,8 @@ class AppServiceProvider extends ServiceProvider
*/ */
public function boot(): void public function boot(): void
{ {
// Validator::extend('phone', function ($attribute, $value, $parameters, $validator) {
return preg_match('/^1[\d]{10}$/', $value);
});
} }
} }

View File

@ -2,7 +2,10 @@
namespace App\Services; namespace App\Services;
use App\Exceptions\AdminValidationException;
use App\Models\User; use App\Models\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Slowlyo\OwlAdmin\Services\AdminService; use Slowlyo\OwlAdmin\Services\AdminService;
/** /**
@ -12,6 +15,23 @@ class UserService extends AdminService
{ {
protected string $modelName = User::class; protected string $modelName = User::class;
public function saving(&$data, $primaryKey = '')
{
$unique = Rule::unique('users', 'phone');
$createRules = [
'phone' => ['required', $unique, 'phone']
];
$updateRules = [
'phone' => ['phone', $unique->ignore($primaryKey)]
];
$validator = Validator::make($data, $primaryKey ? $updateRules : $createRules);
if ($validator->fails()) {
throw new AdminValidationException($validator->errors());
}
}
public function sortable($query) public function sortable($query)
{ {
$query->orderByDesc('id'); $query->orderByDesc('id');

View File

@ -134,7 +134,7 @@ return [
'string' => ':Attribute 必须是一个字符串。', 'string' => ':Attribute 必须是一个字符串。',
'timezone' => ':Attribute 必须是一个合法的时区值。', 'timezone' => ':Attribute 必须是一个合法的时区值。',
'ulid' => ':Attribute 必须是有效的 ULID。', 'ulid' => ':Attribute 必须是有效的 ULID。',
'unique' => ':Attribute 已经存在。', 'unique' => ':Attribute :input 已经存在。',
'uploaded' => ':Attribute 上传失败。', 'uploaded' => ':Attribute 上传失败。',
'uppercase' => ':Attribute 必须大写', 'uppercase' => ':Attribute 必须大写',
'url' => ':Attribute 格式不正确。', 'url' => ':Attribute 格式不正确。',
@ -182,7 +182,7 @@ return [
'number' => '数字', 'number' => '数字',
'password' => '密码', 'password' => '密码',
'password_confirmation' => '确认密码', 'password_confirmation' => '确认密码',
'phone' => '电话', 'phone' => '手机号',
'photo' => '照片', 'photo' => '照片',
'postal_code' => '邮政编码', 'postal_code' => '邮政编码',
'price' => '价格', 'price' => '价格',
@ -213,5 +213,5 @@ return [
'year' => '年', 'year' => '年',
'money' => '金额', 'money' => '金额',
], ],
'phone' => '不是一个有效的手机号', 'phone' => ':input 不是一个有效的手机号',
]; ];

View File

@ -3,7 +3,6 @@
namespace Tests\Feature; namespace Tests\Feature;
// use Illuminate\Foundation\Testing\RefreshDatabase; // use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase; use Tests\TestCase;
class ExampleTest extends TestCase class ExampleTest extends TestCase
@ -13,6 +12,5 @@ class ExampleTest extends TestCase
*/ */
public function test_the_application_returns_a_successful_response(): void public function test_the_application_returns_a_successful_response(): void
{ {
dump(now());
} }
} }