WalletController.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. namespace App\Http\Controllers\Coach;
  3. use App\Http\Controllers\Controller;
  4. use App\Services\Coach\WalletService;
  5. use App\Traits\ResponseTrait;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Support\Facades\Auth;
  8. /**
  9. * @group 技师端
  10. *
  11. * 钱包相关的API接口
  12. */
  13. class WalletController extends Controller
  14. {
  15. use ResponseTrait;
  16. protected WalletService $service;
  17. public function __construct(WalletService $service)
  18. {
  19. $this->service = $service;
  20. }
  21. /**
  22. * [钱包]获取钱包信息
  23. *
  24. * @description 获取技师钱包余额和收入统计信息
  25. *
  26. * @authenticated
  27. *
  28. * @response {
  29. * "data": {
  30. * "balance": "1000.00",
  31. * "frozen_amount": "0.00",
  32. * "total_income": "5000.00",
  33. * "total_withdraw": "4000.00",
  34. * "today_income": "100.00",
  35. * "month_income": "2000.00",
  36. * "last_month_income": "3000.00"
  37. * }
  38. * }
  39. */
  40. public function getWallet()
  41. {
  42. return $this->success($this->service->getWallet(Auth::user()->id));
  43. }
  44. /**
  45. * [钱包]获取钱包流水记录
  46. *
  47. * @description 获取技师钱包的收支明细记录
  48. *
  49. * @authenticated
  50. *
  51. * @queryParam type integer 记录类型(1:收入 2:支出) Example: 1
  52. * @queryParam start_date date 开始日期 Example: 2024-01-01
  53. * @queryParam end_date date 结束日期 Example: 2024-03-21
  54. * @queryParam min_amount numeric 最小金额 Example: 100
  55. * @queryParam max_amount numeric 最大金额 Example: 1000
  56. * @queryParam status integer 交易状态(1:成功 2:处理中 3:失败) Example: 1
  57. * @queryParam sort_field string 排序字段(created_at, amount, balance) Example: created_at
  58. * @queryParam sort_order string 排序顺序(asc, desc) Example: desc
  59. * @queryParam page integer 页码 Example: 1
  60. * @queryParam per_page integer 每页数量 Example: 10
  61. *
  62. * @response {
  63. * "data": {
  64. * "items": [
  65. * {
  66. * "id": 1,
  67. * "amount": "100.00",
  68. * "type": 1,
  69. * "remark": "订单收入",
  70. * "created_at": "2024-03-21 10:00:00"
  71. * }
  72. * ],
  73. * "total": 100
  74. * }
  75. * }
  76. */
  77. public function getWalletRecords(Request $request)
  78. {
  79. $params = $request->validate([
  80. 'type' => 'nullable|integer|in:1,2',
  81. 'start_date' => 'nullable|date',
  82. 'end_date' => 'nullable|date|after_or_equal:start_date',
  83. 'min_amount' => 'nullable|numeric|min:0',
  84. 'max_amount' => 'nullable|numeric|gt:min_amount',
  85. 'status' => 'nullable|integer|in:1,2,3',
  86. 'sort_field' => 'nullable|string|in:created_at,amount,balance',
  87. 'sort_order' => 'nullable|string|in:asc,desc',
  88. 'page' => 'nullable|integer|min:1',
  89. 'per_page' => 'nullable|integer|min:1|max:50',
  90. ]);
  91. return $this->success($this->service->getWalletRecords(Auth::user()->id, $params));
  92. }
  93. /**
  94. * [钱包]申请提现
  95. *
  96. * @description 技师申请提现到指定账户
  97. *
  98. * @authenticated
  99. *
  100. * @bodyParam amount numeric required 提现金额(最低100元) Example: 100.00
  101. * @bodyParam withdraw_type integer required 提现方式(1:微信 2:支付宝 3:银行卡) Example: 1
  102. * @bodyParam withdraw_account string required 提现账号 Example: example@alipay.com
  103. * @bodyParam withdraw_account_name string required 提现账户名称 Example: 张三
  104. *
  105. * @response {
  106. * "message": "提现申请已提交",
  107. * "trans_no": "W202403211234567890",
  108. * "amount": "100.00",
  109. * "status": "处理中"
  110. * }
  111. * @response 422 {
  112. * "message": "可提现余额不足"
  113. * }
  114. */
  115. public function withdraw(Request $request)
  116. {
  117. // 验证基本参数
  118. $data = $request->validate([
  119. 'amount' => 'required|numeric|min:100',
  120. 'withdraw_type' => 'required|integer|in:1,2,3',
  121. 'withdraw_account' => 'required|string|max:100',
  122. 'withdraw_account_name' => 'required|string|max:50',
  123. ]);
  124. // 根据提现方式验证账号格式
  125. switch ($data['withdraw_type']) {
  126. case 1: // 微信
  127. $request->validate([
  128. 'withdraw_account' => [
  129. 'required',
  130. 'string',
  131. 'regex:/^[a-zA-Z][a-zA-Z\d_-]{5,19}$/',
  132. 'max:20',
  133. ],
  134. ], [
  135. 'withdraw_account.regex' => '微信号格式不正确',
  136. ]);
  137. break;
  138. case 2: // 支付宝
  139. $request->validate([
  140. 'withdraw_account' => [
  141. 'required',
  142. 'string',
  143. function ($attribute, $value, $fail) {
  144. if (! filter_var($value, FILTER_VALIDATE_EMAIL) && ! preg_match('/^1[3-9]\d{9}$/', $value)) {
  145. $fail('支付宝账号必须是有效的邮箱或手机号');
  146. }
  147. },
  148. ],
  149. ]);
  150. break;
  151. case 3: // 银行卡
  152. $request->validate([
  153. 'withdraw_account' => [
  154. 'required',
  155. 'string',
  156. 'regex:/^\d{16,19}$/',
  157. ],
  158. ], [
  159. 'withdraw_account.regex' => '银行卡号格式不正确',
  160. ]);
  161. break;
  162. }
  163. // 验证提现账户名称
  164. abort_if(mb_strlen($data['withdraw_account_name']) < 2, 422, '提现账户名称至少2个字符');
  165. abort_if(! preg_match('/^[\x{4e00}-\x{9fa5}a-zA-Z\s]+$/u', $data['withdraw_account_name']), 422, '提现账户名称只能包含中文、英文字母和空格');
  166. return $this->success($this->service->withdraw(Auth::user()->id, $data));
  167. }
  168. }