|
|
@@ -0,0 +1,258 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Module\Transfer\Validations;
|
|
|
+
|
|
|
+use App\Module\Transfer\Validators\TransferAppValidator;
|
|
|
+use App\Module\Transfer\Validators\AmountValidator;
|
|
|
+use UCore\Validation\ValidationCore;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 转出验证类
|
|
|
+ */
|
|
|
+class TransferOutValidation extends ValidationCore
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 验证规则
|
|
|
+ */
|
|
|
+ protected function rules(): array
|
|
|
+ {
|
|
|
+ return [
|
|
|
+ 'transfer_app_id' => 'required|integer|min:1',
|
|
|
+ 'user_id' => 'required|integer|min:1',
|
|
|
+ 'amount' => 'required|string',
|
|
|
+ 'password' => 'required|string|min:6',
|
|
|
+ 'google_code' => 'nullable|string|size:6',
|
|
|
+ 'out_user_id' => 'nullable|string|max:50',
|
|
|
+ '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',
|
|
|
+ 'user_id.required' => '用户ID不能为空',
|
|
|
+ 'user_id.integer' => '用户ID必须为整数',
|
|
|
+ 'user_id.min' => '用户ID必须大于0',
|
|
|
+ 'amount.required' => '金额不能为空',
|
|
|
+ 'amount.string' => '金额必须为字符串格式',
|
|
|
+ 'password.required' => '安全密码不能为空',
|
|
|
+ 'password.string' => '安全密码必须为字符串',
|
|
|
+ 'password.min' => '安全密码长度不能少于6位',
|
|
|
+ 'google_code.string' => 'Google验证码必须为字符串',
|
|
|
+ 'google_code.size' => 'Google验证码必须为6位数字',
|
|
|
+ 'out_user_id.string' => '外部用户ID必须为字符串',
|
|
|
+ 'out_user_id.max' => '外部用户ID长度不能超过50个字符',
|
|
|
+ '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());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证金额格式
|
|
|
+ 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']) && isset($this->data['password'])) {
|
|
|
+ $this->validateUserPassword();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证Google验证码(如果提供)
|
|
|
+ if (isset($this->data['user_id']) && isset($this->data['google_code'])) {
|
|
|
+ $this->validateGoogleCode();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证用户资金余额
|
|
|
+ if (isset($this->data['user_id']) && isset($this->data['transfer_app_id']) && isset($this->data['amount'])) {
|
|
|
+ $this->validateUserBalance();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证用户安全密码
|
|
|
+ */
|
|
|
+ protected function validateUserPassword(): void
|
|
|
+ {
|
|
|
+ $userId = $this->data['user_id'];
|
|
|
+ $password = $this->data['password'];
|
|
|
+
|
|
|
+ // 这里应该调用用户模块的密码验证服务
|
|
|
+ // 示例代码:
|
|
|
+ // if (!UserService::verifyPassword($userId, $password)) {
|
|
|
+ // $this->addError('password', '安全密码错误');
|
|
|
+ // }
|
|
|
+
|
|
|
+ // 临时验证逻辑(实际项目中应该替换为真实的密码验证)
|
|
|
+ if (strlen($password) < 6) {
|
|
|
+ $this->addError('password', '安全密码长度不能少于6位');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证Google验证码
|
|
|
+ */
|
|
|
+ protected function validateGoogleCode(): void
|
|
|
+ {
|
|
|
+ $userId = $this->data['user_id'];
|
|
|
+ $googleCode = $this->data['google_code'];
|
|
|
+
|
|
|
+ // 验证格式
|
|
|
+ if (!preg_match('/^\d{6}$/', $googleCode)) {
|
|
|
+ $this->addError('google_code', 'Google验证码必须为6位数字');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 这里应该调用Google验证码验证服务
|
|
|
+ // 示例代码:
|
|
|
+ // if (!GoogleAuthService::verify($userId, $googleCode)) {
|
|
|
+ // $this->addError('google_code', 'Google验证码错误');
|
|
|
+ // }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证用户资金余额
|
|
|
+ */
|
|
|
+ protected function validateUserBalance(): void
|
|
|
+ {
|
|
|
+ $userId = $this->data['user_id'];
|
|
|
+ $appId = $this->data['transfer_app_id'];
|
|
|
+ $amount = $this->data['amount'];
|
|
|
+
|
|
|
+ // 获取应用配置
|
|
|
+ $app = \App\Module\Transfer\Models\TransferApp::find($appId);
|
|
|
+ if (!$app) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算内部金额
|
|
|
+ $internalAmount = bcmul($amount, (string) $app->exchange_rate, 10);
|
|
|
+
|
|
|
+ // 这里应该调用Fund模块验证余额
|
|
|
+ // 示例代码:
|
|
|
+ // if (!FundService::hasBalance($userId, $app->fund_id, $internalAmount)) {
|
|
|
+ // $this->addError('amount', '余额不足');
|
|
|
+ // }
|
|
|
+
|
|
|
+ // 验证最小转出金额
|
|
|
+ $minAmount = '0.01';
|
|
|
+ if (bccomp($amount, $minAmount, 10) < 0) {
|
|
|
+ $this->addError('amount', "转出金额不能少于 {$minAmount}");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证最大转出金额
|
|
|
+ $maxAmount = '1000000.00';
|
|
|
+ if (bccomp($amount, $maxAmount, 10) > 0) {
|
|
|
+ $this->addError('amount', "转出金额不能超过 {$maxAmount}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证转出权限
|
|
|
+ */
|
|
|
+ protected function validateTransferOutPermission(): 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->supportsTransferOut()) {
|
|
|
+ $this->addError('transfer_app_id', '该应用不支持转出操作');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查应用是否启用
|
|
|
+ if (!$app->is_enabled) {
|
|
|
+ $this->addError('transfer_app_id', '应用已禁用');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证用户转出限制
|
|
|
+ */
|
|
|
+ protected function validateUserTransferLimits(): void
|
|
|
+ {
|
|
|
+ if (!isset($this->data['user_id']) || !isset($this->data['amount'])) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ $userId = $this->data['user_id'];
|
|
|
+ $amount = $this->data['amount'];
|
|
|
+
|
|
|
+ // 检查今日转出次数限制
|
|
|
+ $todayCount = \App\Module\Transfer\Models\TransferOrder::where('user_id', $userId)
|
|
|
+ ->where('type', \App\Module\Transfer\Enums\TransferType::OUT)
|
|
|
+ ->whereDate('created_at', today())
|
|
|
+ ->count();
|
|
|
+
|
|
|
+ if ($todayCount >= 10) {
|
|
|
+ $this->addError('user_id', '今日转出次数已达上限(10次)');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查今日转出金额限制
|
|
|
+ $todayAmount = \App\Module\Transfer\Models\TransferOrder::where('user_id', $userId)
|
|
|
+ ->where('type', \App\Module\Transfer\Enums\TransferType::OUT)
|
|
|
+ ->whereDate('created_at', today())
|
|
|
+ ->sum('amount');
|
|
|
+
|
|
|
+ $dailyLimit = '50000.00';
|
|
|
+ $newTotal = bcadd((string) $todayAmount, $amount, 10);
|
|
|
+
|
|
|
+ if (bccomp($newTotal, $dailyLimit, 10) > 0) {
|
|
|
+ $this->addError('amount', "今日转出金额已达上限({$dailyLimit})");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行验证后的处理
|
|
|
+ */
|
|
|
+ protected function afterValidation(): void
|
|
|
+ {
|
|
|
+ // 验证转出权限
|
|
|
+ $this->validateTransferOutPermission();
|
|
|
+
|
|
|
+ // 验证用户转出限制
|
|
|
+ $this->validateUserTransferLimits();
|
|
|
+
|
|
|
+ // 格式化金额
|
|
|
+ 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 !== '';
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|