UserService 添加表单验证
parent
83cf255f98
commit
b6a620e935
|
|
@ -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
|
||||||
|
|
@ -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'],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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');
|
||||||
|
|
|
||||||
|
|
@ -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 不是一个有效的手机号',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue