--- 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 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 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