Files
2026-08-31 11:33:59 +08:00

312 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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