|
@@ -2,8 +2,12 @@
|
|
|
|
|
|
namespace App\Services\Coach;
|
|
|
|
|
|
+use App\Enums\WithdrawStatus;
|
|
|
use App\Models\MemberUser;
|
|
|
+use App\Models\Wallet;
|
|
|
use App\Models\WalletTransRecord;
|
|
|
+use App\Models\WalletWithdrawRecord;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
|
|
class WalletService
|
|
@@ -83,7 +87,7 @@ class WalletService
|
|
|
})
|
|
|
// 添加交易状态筛选
|
|
|
->when(isset($params['status']), function ($query) use ($params) {
|
|
|
- return $query->where('status', $params['status']);
|
|
|
+ return $query->where('state', $params['status']);
|
|
|
})
|
|
|
// 添加排序选项
|
|
|
->when(
|
|
@@ -131,7 +135,7 @@ class WalletService
|
|
|
'owner_type' => $this->formatOwnerType($record->owner_type),
|
|
|
'owner_id' => $record->owner_id,
|
|
|
'remark' => $record->remark,
|
|
|
- 'status' => $this->formatStatus($record->status),
|
|
|
+ 'state' => $this->formatStatus($record->state),
|
|
|
'created_at' => $record->created_at->format('Y-m-d H:i:s'),
|
|
|
];
|
|
|
});
|
|
@@ -161,6 +165,96 @@ class WalletService
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 技师钱包提现
|
|
|
+ *
|
|
|
+ * @param int $userId 技师用户ID
|
|
|
+ * @param array $data 提现数据
|
|
|
+ * @return array
|
|
|
+ *
|
|
|
+ * @throws \Exception
|
|
|
+ */
|
|
|
+ public function withdraw(int $userId, array $data)
|
|
|
+ {
|
|
|
+ return DB::transaction(function () use ($userId, $data) {
|
|
|
+ try {
|
|
|
+ // 获取用户和技师信息
|
|
|
+ $user = MemberUser::with(['coach', 'coach.wallet'])->findOrFail($userId);
|
|
|
+ abort_if(! $user->coach, 404, '技师信息不存在');
|
|
|
+ abort_if(! $user->coach->wallet, 404, '钱包信息不存在');
|
|
|
+
|
|
|
+ // 锁定钱包记录
|
|
|
+ $wallet = Wallet::where('id', $user->coach->wallet->id)
|
|
|
+ ->lockForUpdate()
|
|
|
+ ->first();
|
|
|
+ // TODO: 提现金额限制
|
|
|
+ // 验证提现金额
|
|
|
+ $amount = $data['amount'];
|
|
|
+ abort_if($amount <= 100, 422, '提现金额必须大于100元');
|
|
|
+ abort_if($amount > $wallet->available_balance, 422, '可提现余额不足');
|
|
|
+
|
|
|
+ // 生成交易流水号
|
|
|
+ $transNo = 'W'.date('YmdHis').mt_rand(1000, 9999);
|
|
|
+
|
|
|
+ // 创建提现记录
|
|
|
+ $withdraw = WalletWithdrawRecord::create([
|
|
|
+ 'wallet_id' => $wallet->id, // 钱包ID
|
|
|
+ 'trans_no' => $transNo, // 交易流水号
|
|
|
+ 'amount' => $amount, // 提现金额
|
|
|
+ 'withdraw_type' => $data['withdraw_type'], // 提现方式(1:微信 2:支付宝 3:银行卡)
|
|
|
+ 'withdraw_account' => $data['withdraw_account'], // 提现账号
|
|
|
+ 'withdraw_account_name' => $data['withdraw_account_name'], // 提现账户名称
|
|
|
+ 'state' => WithdrawStatus::PROCESSING, // 提现状态
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // TODO: 创建交易记录字段需关联枚举
|
|
|
+ // 创建交易记录
|
|
|
+ $record = WalletTransRecord::create([
|
|
|
+ 'wallet_id' => $wallet->id,
|
|
|
+ 'trans_no' => $transNo,
|
|
|
+ 'trans_type' => 2, // 支出
|
|
|
+ 'amount' => -$amount,
|
|
|
+ 'before_balance' => $wallet->available_balance,
|
|
|
+ 'after_balance' => $wallet->available_balance - $amount,
|
|
|
+ 'owner_type' => WalletWithdrawRecord::class,
|
|
|
+ 'owner_id' => $withdraw->id,
|
|
|
+ 'remark' => '提现申请',
|
|
|
+ 'state' => 2, // 处理中
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 冻结提现金额
|
|
|
+ $wallet->decrement('available_balance', $amount);
|
|
|
+ $wallet->increment('frozen_amount', $amount);
|
|
|
+
|
|
|
+ // 记录日志
|
|
|
+ \Log::info('技师提现申请成功', [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'coach_id' => $user->coach->id,
|
|
|
+ 'trans_no' => $transNo,
|
|
|
+ 'amount' => $amount,
|
|
|
+ 'wallet_id' => $wallet->id,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'message' => '提现申请已提交',
|
|
|
+ 'trans_no' => $transNo,
|
|
|
+ 'amount' => number_format($amount, 2, '.', ''),
|
|
|
+ 'state' => '处理中',
|
|
|
+ ];
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ \Log::error('技师提现申请失败', [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'data' => $data,
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ 'file' => $e->getFile(),
|
|
|
+ 'line' => $e->getLine(),
|
|
|
+ ]);
|
|
|
+ throw $e;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 格式化交易类型
|
|
|
*/
|