Files

312 lines
7.6 KiB
Markdown
Raw Permalink Normal View History

2026-08-31 11:33:59 +08:00
---
name: backend-gen-validate
description: Generate validation class for madong module. Supports both app (main project) and plugin targets. Creates validate extending BaseValidate with Laravel validation rules and scene definitions.
globs:
- "app/adminapi/validate/**/*.php"
- "app/api/validate/**/*.php"
- "plugin/**/app/adminapi/validate/**/*.php"
---
# Generate Validate
Create validation class for module.
## File Location
**App (主项目):**
```
app/adminapi/validate/{module}/{Model}Validate.php
```
**Plugin (插件):**
```
plugin/{plugin}/app/adminapi/validate/{module}/{Model}Validate.php
```
## Target Variables
| 变量 | App | Plugin |
|------|-----|--------|
| `{prefix}` | `` (空) | `plugin\{Plugin}` |
| `{ns}` | `app` | `plugin\{Plugin}\app` |
| `{model_ns}` | `app\model` | `plugin\{Plugin}\app\model` |
## Validate Template
```php
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
*/
namespace {ns}\adminapi\validate\{module};
use {model_ns}\{module}\{Model};
use core\base\BaseValidate;
use Illuminate\Validation\Rule;
/**
* {Model}验证器
*
* Class {Model}Validate
*/
class {Model}Validate extends BaseValidate
{
/**
* 验证规则
*/
public function rules(): array
{
// 更新请求优先读取路由 ID;无路由 ID 时兼容请求体中的 ID。
$id = request()->route?->param('id') ?? request()->input('id');
return [
{rules}
];
}
/**
* 验证消息
*/
protected array $message = [
{messages}
];
/**
* 验证场景
*/
protected array $scene = [
'store' => [
{store_fields}
],
'update' => [
{update_fields}
],
];
/**
* 创建验证场景
*/
public function sceneStore(): {Model}Validate
{
return $this->only($this->scene['store']);
}
/**
* 更新验证场景
*/
public function sceneUpdate(): {Model}Validate
{
return $this->only($this->scene['update']);
}
}
```
## Complete Example (App)
```php
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
*/
namespace app\adminapi\validate\member;
use app\model\member\Member;
use core\base\BaseValidate;
use Illuminate\Validation\Rule;
/**
* 会员验证器
*
* Class MemberValidate
*/
class MemberValidate extends BaseValidate
{
/**
* 验证规则
*/
public function rules(): array
{
// 更新请求优先读取路由 ID;无路由 ID 时兼容请求体中的 ID。
$id = request()->route?->param('id') ?? request()->input('id');
return [
'username' => ['required', 'max:50', Rule::unique(Member::class, 'username')->ignore($id, 'id')],
'email' => ['email', 'max:100'],
'phone' => ['max:20'],
'password' => 'required|min:6|max:60',
'nickname' => 'max:50',
'level_id' => 'integer|min:1',
'points' => 'integer|min:0',
'balance' => 'number|min:0',
'gender' => 'in:0,1,2',
'birthday' => 'date',
'enabled' => 'in:0,1',
];
}
/**
* 验证消息
*/
protected array $message = [
'username.required' => '用户名不能为空',
'username.max' => '用户名不能超过50个字符',
'username.unique' => '用户名已存在',
'email.email' => '邮箱格式不正确',
'email.max' => '邮箱不能超过100个字符',
'phone.max' => '手机号格式不正确',
'password.required' => '密码不能为空',
'password.min' => '密码不能少于6个字符',
'password.max' => '密码不能超过60个字符',
'nickname.max' => '昵称不能超过50个字符',
'level_id.integer' => '等级ID必须为整数',
'points.integer' => '积分必须为整数',
'balance.number' => '余额必须为数字',
'gender.in' => '性别值不正确',
'birthday.date' => '生日格式不正确',
'enabled.in' => '状态值不正确',
];
/**
* 验证场景
*/
protected array $scene = [
'store' => [
'username',
'email',
'phone',
'password',
'nickname',
'level_id',
'points',
'balance',
'gender',
'birthday',
'enabled',
],
'update' => [
'username',
'email',
'phone',
'nickname',
'level_id',
'points',
'balance',
'gender',
'birthday',
'enabled',
],
];
/**
* 创建验证场景
*/
public function sceneStore(): MemberValidate
{
return $this->only($this->scene['store']);
}
/**
* 更新验证场景
*/
public function sceneUpdate(): MemberValidate
{
return $this->only($this->scene['update']);
}
}
```
## Validation Rules Reference
| Rule | Example | Description |
|------|---------|-------------|
| required | `'field' => 'required'` | 必填 |
| nullable | `'field' => 'nullable'` | 可为空 |
| integer | `'field' => 'integer'` | 整数 |
| numeric | `'field' => 'numeric'` | 数字 |
| string | `'field' => 'string'` | 字符串 |
| email | `'field' => 'email'` | 邮箱格式 |
| max | `'field' => 'max:50'` | 最大长度 |
| min | `'field' => 'min:6'` | 最小长度 |
| in | `'field' => 'in:0,1,2'` | 枚举值 |
| unique | `'field' => Rule::unique(Model::class)` | 唯一性 |
| date | `'field' => 'date'` | 日期格式 |
| array | `'field' => 'array'` | 数组 |
| alpha | `'field' => 'alpha'` | 仅字母 |
| alpha_num | `'field' => 'alpha_num'` | 字母数字 |
## 更新唯一性校验
通用 `BaseService.update({ id, ...payload })` 会将 `id` 生成 REST URL:`PUT /resource/{id}`,并从请求体移除该字段。因此唯一性校验应从路由读取当前记录 ID:
```php
$id = request()->route?->param('id');
Rule::unique(Model::class, 'code')->ignore($id, 'id');
```
配置类编辑表单中的隐藏 `id` 字段不能配置 `ifDetail: true`;该属性会令字段不参与编辑表单,进而造成 `PUT /resource/undefined` 和自身重复误判。
## Custom Scene Example
```php
/**
* 重置密码验证
*/
public function sceneResetPassword(): MemberValidate
{
return $this->only([])
->append('id', 'require|integer|min:1')
->append('password', 'require|min:6|max:20');
}
/**
* 状态更新验证
*/
public function sceneStatus(): MemberValidate
{
return $this->only([])
->append('id', 'require|integer|min:1')
->append('status', 'require|in:0,1');
}
/**
* 批量删除验证
*/
public function sceneBatchDelete(): MemberValidate
{
return $this->only([])
->append('ids', 'require|array|min:1');
}
```
## Auto-generation Checklist
When generating validate:
- [ ] Set correct namespace based on target
- [ ] Import BaseValidate
- [ ] Import Model class
- [ ] Define rules() method with Laravel validation
- [ ] Use Rule::unique() for unique fields
- [ ] Define $message for custom error messages
- [ ] Define $scene for validation scenes
- [ ] Implement sceneStore() method
- [ ] Implement sceneUpdate() method