TransferOutValidation.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. namespace App\Module\Transfer\Validations;
  3. use App\Module\Transfer\Validators\TransferAppValidator;
  4. use App\Module\Transfer\Validators\AmountValidator;
  5. use UCore\Validation\ValidationCore;
  6. /**
  7. * 转出验证类
  8. */
  9. class TransferOutValidation extends ValidationCore
  10. {
  11. /**
  12. * 验证规则
  13. */
  14. protected function rules(): array
  15. {
  16. return [
  17. 'transfer_app_id' => 'required|integer|min:1',
  18. 'user_id' => 'required|integer|min:1',
  19. 'amount' => 'required|string',
  20. 'password' => 'required|string|min:6',
  21. 'google_code' => 'nullable|string|size:6',
  22. 'out_user_id' => 'nullable|string|max:50',
  23. 'remark' => 'nullable|string|max:255',
  24. 'callback_data' => 'nullable|array',
  25. ];
  26. }
  27. /**
  28. * 验证消息
  29. */
  30. protected function messages(): array
  31. {
  32. return [
  33. 'transfer_app_id.required' => '应用ID不能为空',
  34. 'transfer_app_id.integer' => '应用ID必须为整数',
  35. 'transfer_app_id.min' => '应用ID必须大于0',
  36. 'user_id.required' => '用户ID不能为空',
  37. 'user_id.integer' => '用户ID必须为整数',
  38. 'user_id.min' => '用户ID必须大于0',
  39. 'amount.required' => '金额不能为空',
  40. 'amount.string' => '金额必须为字符串格式',
  41. 'password.required' => '安全密码不能为空',
  42. 'password.string' => '安全密码必须为字符串',
  43. 'password.min' => '安全密码长度不能少于6位',
  44. 'google_code.string' => 'Google验证码必须为字符串',
  45. 'google_code.size' => 'Google验证码必须为6位数字',
  46. 'out_user_id.string' => '外部用户ID必须为字符串',
  47. 'out_user_id.max' => '外部用户ID长度不能超过50个字符',
  48. 'remark.string' => '备注必须为字符串',
  49. 'remark.max' => '备注长度不能超过255个字符',
  50. 'callback_data.array' => '回调数据必须为数组格式',
  51. ];
  52. }
  53. /**
  54. * 自定义验证
  55. */
  56. protected function customValidation(): void
  57. {
  58. // 验证应用配置
  59. $appValidator = new TransferAppValidator($this->data['transfer_app_id'] ?? 0);
  60. if (!$appValidator->validate()) {
  61. $this->addError('transfer_app_id', $appValidator->getError());
  62. }
  63. // 验证金额格式
  64. if (isset($this->data['amount'])) {
  65. $amountValidator = new AmountValidator($this->data['amount']);
  66. if (!$amountValidator->validate()) {
  67. $this->addError('amount', $amountValidator->getError());
  68. }
  69. }
  70. // 验证用户安全密码
  71. if (isset($this->data['user_id']) && isset($this->data['password'])) {
  72. $this->validateUserPassword();
  73. }
  74. // 验证Google验证码(如果提供)
  75. if (isset($this->data['user_id']) && isset($this->data['google_code'])) {
  76. $this->validateGoogleCode();
  77. }
  78. // 验证用户资金余额
  79. if (isset($this->data['user_id']) && isset($this->data['transfer_app_id']) && isset($this->data['amount'])) {
  80. $this->validateUserBalance();
  81. }
  82. }
  83. /**
  84. * 验证用户安全密码
  85. */
  86. protected function validateUserPassword(): void
  87. {
  88. $userId = $this->data['user_id'];
  89. $password = $this->data['password'];
  90. // 这里应该调用用户模块的密码验证服务
  91. // 示例代码:
  92. // if (!UserService::verifyPassword($userId, $password)) {
  93. // $this->addError('password', '安全密码错误');
  94. // }
  95. // 临时验证逻辑(实际项目中应该替换为真实的密码验证)
  96. if (strlen($password) < 6) {
  97. $this->addError('password', '安全密码长度不能少于6位');
  98. }
  99. }
  100. /**
  101. * 验证Google验证码
  102. */
  103. protected function validateGoogleCode(): void
  104. {
  105. $userId = $this->data['user_id'];
  106. $googleCode = $this->data['google_code'];
  107. // 验证格式
  108. if (!preg_match('/^\d{6}$/', $googleCode)) {
  109. $this->addError('google_code', 'Google验证码必须为6位数字');
  110. return;
  111. }
  112. // 这里应该调用Google验证码验证服务
  113. // 示例代码:
  114. // if (!GoogleAuthService::verify($userId, $googleCode)) {
  115. // $this->addError('google_code', 'Google验证码错误');
  116. // }
  117. }
  118. /**
  119. * 验证用户资金余额
  120. */
  121. protected function validateUserBalance(): void
  122. {
  123. $userId = $this->data['user_id'];
  124. $appId = $this->data['transfer_app_id'];
  125. $amount = $this->data['amount'];
  126. // 获取应用配置
  127. $app = \App\Module\Transfer\Models\TransferApp::find($appId);
  128. if (!$app) {
  129. return;
  130. }
  131. // 计算内部金额
  132. $internalAmount = bcmul($amount, (string) $app->exchange_rate, 10);
  133. // 这里应该调用Fund模块验证余额
  134. // 示例代码:
  135. // if (!FundService::hasBalance($userId, $app->fund_id, $internalAmount)) {
  136. // $this->addError('amount', '余额不足');
  137. // }
  138. // 验证最小转出金额
  139. $minAmount = '0.01';
  140. if (bccomp($amount, $minAmount, 10) < 0) {
  141. $this->addError('amount', "转出金额不能少于 {$minAmount}");
  142. }
  143. // 验证最大转出金额
  144. $maxAmount = '1000000.00';
  145. if (bccomp($amount, $maxAmount, 10) > 0) {
  146. $this->addError('amount', "转出金额不能超过 {$maxAmount}");
  147. }
  148. }
  149. /**
  150. * 验证转出权限
  151. */
  152. protected function validateTransferOutPermission(): void
  153. {
  154. if (!isset($this->data['transfer_app_id'])) {
  155. return;
  156. }
  157. $appId = $this->data['transfer_app_id'];
  158. // 获取应用配置
  159. $app = \App\Module\Transfer\Models\TransferApp::find($appId);
  160. if (!$app) {
  161. return;
  162. }
  163. // 检查应用是否支持转出
  164. if (!$app->supportsTransferOut()) {
  165. $this->addError('transfer_app_id', '该应用不支持转出操作');
  166. }
  167. // 检查应用是否启用
  168. if (!$app->is_enabled) {
  169. $this->addError('transfer_app_id', '应用已禁用');
  170. }
  171. }
  172. /**
  173. * 验证用户转出限制
  174. */
  175. protected function validateUserTransferLimits(): void
  176. {
  177. if (!isset($this->data['user_id']) || !isset($this->data['amount'])) {
  178. return;
  179. }
  180. $userId = $this->data['user_id'];
  181. $amount = $this->data['amount'];
  182. // 检查今日转出次数限制
  183. $todayCount = \App\Module\Transfer\Models\TransferOrder::where('user_id', $userId)
  184. ->where('type', \App\Module\Transfer\Enums\TransferType::OUT)
  185. ->whereDate('created_at', today())
  186. ->count();
  187. if ($todayCount >= 10) {
  188. $this->addError('user_id', '今日转出次数已达上限(10次)');
  189. }
  190. // 检查今日转出金额限制
  191. $todayAmount = \App\Module\Transfer\Models\TransferOrder::where('user_id', $userId)
  192. ->where('type', \App\Module\Transfer\Enums\TransferType::OUT)
  193. ->whereDate('created_at', today())
  194. ->sum('amount');
  195. $dailyLimit = '50000.00';
  196. $newTotal = bcadd((string) $todayAmount, $amount, 10);
  197. if (bccomp($newTotal, $dailyLimit, 10) > 0) {
  198. $this->addError('amount', "今日转出金额已达上限({$dailyLimit})");
  199. }
  200. }
  201. /**
  202. * 执行验证后的处理
  203. */
  204. protected function afterValidation(): void
  205. {
  206. // 验证转出权限
  207. $this->validateTransferOutPermission();
  208. // 验证用户转出限制
  209. $this->validateUserTransferLimits();
  210. // 格式化金额
  211. if (isset($this->data['amount'])) {
  212. $this->data['amount'] = number_format((float) $this->data['amount'], 10, '.', '');
  213. }
  214. // 清理回调数据
  215. if (isset($this->data['callback_data']) && is_array($this->data['callback_data'])) {
  216. $this->data['callback_data'] = array_filter($this->data['callback_data'], function ($value) {
  217. return $value !== null && $value !== '';
  218. });
  219. }
  220. }
  221. }