'required|integer|min:1', 'business_id' => 'required|string|max:100', 'out_user_id' => 'nullable|string|max:50', 'user_id' => 'required|integer|min:1', 'amount' => 'required|string', 'remark' => 'nullable|string|max:255', 'callback_data' => 'nullable|array', ]; } /** * 验证消息 */ protected function messages(): array { return [ 'transfer_app_id.required' => '应用ID不能为空', 'transfer_app_id.integer' => '应用ID必须为整数', 'transfer_app_id.min' => '应用ID必须大于0', 'business_id.required' => '业务订单ID不能为空', 'business_id.string' => '业务订单ID必须为字符串', 'business_id.max' => '业务订单ID长度不能超过100个字符', 'out_user_id.string' => '外部用户ID必须为字符串', 'out_user_id.max' => '外部用户ID长度不能超过50个字符', 'user_id.required' => '用户ID不能为空', 'user_id.integer' => '用户ID必须为整数', 'user_id.min' => '用户ID必须大于0', 'amount.required' => '金额不能为空', 'amount.string' => '金额必须为字符串格式', 'remark.string' => '备注必须为字符串', 'remark.max' => '备注长度不能超过255个字符', 'callback_data.array' => '回调数据必须为数组格式', ]; } /** * 自定义验证 */ protected function customValidation(): void { // 验证应用配置 $appValidator = new TransferAppValidator($this->data['transfer_app_id'] ?? 0); if (!$appValidator->validate()) { $this->addError('transfer_app_id', $appValidator->getError()); } // 验证业务ID唯一性 if (isset($this->data['business_id']) && isset($this->data['transfer_app_id'])) { $businessIdValidator = new BusinessIdValidator( $this->data['business_id'], $this->data['transfer_app_id'] ); if (!$businessIdValidator->validate()) { $this->addError('business_id', $businessIdValidator->getError()); } } // 验证金额格式 if (isset($this->data['amount'])) { $amountValidator = new AmountValidator($this->data['amount']); if (!$amountValidator->validate()) { $this->addError('amount', $amountValidator->getError()); } } // 验证用户是否存在 if (isset($this->data['user_id'])) { $userId = $this->data['user_id']; // 这里可以调用用户模块的验证服务 // if (!UserService::exists($userId)) { // $this->addError('user_id', '用户不存在'); // } } // 验证回调数据格式 if (isset($this->data['callback_data']) && is_array($this->data['callback_data'])) { $callbackData = $this->data['callback_data']; // 检查回调数据大小(限制为1KB) $jsonSize = strlen(json_encode($callbackData, JSON_UNESCAPED_UNICODE)); if ($jsonSize > 1024) { $this->addError('callback_data', '回调数据过大,不能超过1KB'); } // 检查是否包含敏感字段 $forbiddenKeys = ['password', 'token', 'secret', 'key']; foreach ($forbiddenKeys as $key) { if (array_key_exists($key, $callbackData)) { $this->addError('callback_data', "回调数据不能包含敏感字段: {$key}"); break; } } } } /** * 验证转入权限 */ protected function validateTransferInPermission(): void { if (!isset($this->data['transfer_app_id'])) { return; } $appId = $this->data['transfer_app_id']; // 获取应用配置 $app = \App\Module\Transfer\Models\TransferApp::find($appId); if (!$app) { return; } // 检查应用是否支持转入 if (!$app->supportsTransferIn()) { $this->addError('transfer_app_id', '该应用不支持转入操作'); } // 检查应用是否启用 if (!$app->is_enabled) { $this->addError('transfer_app_id', '应用已禁用'); } } /** * 执行验证后的处理 */ protected function afterValidation(): void { // 验证转入权限 $this->validateTransferInPermission(); // 格式化金额(确保精度) if (isset($this->data['amount'])) { $this->data['amount'] = number_format((float) $this->data['amount'], 10, '.', ''); } // 清理回调数据 if (isset($this->data['callback_data']) && is_array($this->data['callback_data'])) { // 移除空值 $this->data['callback_data'] = array_filter($this->data['callback_data'], function ($value) { return $value !== null && $value !== ''; }); } } }