diff --git a/admin/controllers/base/DivideAccountController.php b/admin/controllers/base/DivideAccountController.php index 6bd6aad..2e35b17 100644 --- a/admin/controllers/base/DivideAccountController.php +++ b/admin/controllers/base/DivideAccountController.php @@ -137,18 +137,29 @@ class DivideAccountController extends BaseAdminController */ public function actionPlatformApply() { + // 获取前端传递的POST数据 $post = \Yii::$app->request->post(); + + // 对POST数据进行验证,确保必要的字段不为空 $this->requestValidate($post, [ [['apply_cash', 'bank_user_name', 'bank_card', 'bank_name', 'bank_account_type', 'user_type'], 'required'] ]); - if ($post['apply_cash']<3){ + + // 检查申请提现金额是否大于等于3元 + if ($post['apply_cash'] < 3) { throw new \yii\db\Exception('申请提现金额最少不能小于3元'); } + + // 获取当前用户信息 $user = \Yii::$app->user->identity; + // 检查用户角色是否为超级管理员 if ($user->role != UserRoleEnum::SUPER_ADMIN) throw new \yii\base\Exception('您还不是超级管理员,没有权限申请打款'); + + // 检查用户类型是否正确 if ($post['user_type'] != 2) throw new \yii\db\Exception('用户类型错误'); + // 对公账户和私人账户的额外验证 if ($post['bank_account_type'] == 1 || $post['bank_account_type'] == 5) { if (empty($post['bank_no'])) { throw new \yii\base\Exception('bank_no不能为空'); @@ -161,53 +172,66 @@ class DivideAccountController extends BaseAdminController } } + // 数据库事务开始 $t = \Yii::$app->db->beginTransaction(); try { + // 生成订单号 $order_no = 'DK' . time() . rand(111111, 999999); + + // 查询账户信息 $Account = CashAccount::find()->where([ 'user_type' => 2, 'user_id' => 0, ])->one(); if (!$Account) throw new Exception('账号不存在'); - if (bcsub($Account->able_cash,$Account->frozen_cash,2) < $post['apply_cash']) + + // 检查账户是否有足够的可提现金额 + if (bcsub($Account->able_cash, $Account->frozen_cash, 2) < $post['apply_cash']) throw new Exception('sorry,您的账户没有那么多提现金额'); + // 更新账户的冻结金额 $CashAccount = CashAccount::find()->where([ - 'user_type' => 2,//平台 + 'user_type' => 2, //平台 'user_id' => 0, ])->one(); -// $CashAccount->able_cash = bcsub($CashAccount->able_cash, $post['apply_cash'], 2); $CashAccount->frozen_cash = bcadd($post['apply_cash'], $CashAccount->frozen_cash, 2); $CashAccount->last_apply_time = date('Y-m-d H:i:s', time()); $CashAccount->saveOrFail(); + // 计算手续费 +// $qianliuwu = bcdiv(0.65, 100, 4); +// $shouxufei = bcadd(bcmul($post['apply_cash'], $qianliuwu, 2), 2, 3); + // TODO 暂时不计算手续费 + $shouxufei = '0'; - $qianliuwu=bcdiv(0.65,100,4); - $shouxufei=bcadd(bcmul($post['apply_cash'],$qianliuwu,2),2,3); - + // 创建提现申请记录 $CashApply = new CashApply(); $CashApply->user_type = 2; - $CashApply->user_id = 0;//用户ID + $CashApply->user_id = 0; //用户ID $CashApply->order_no = $order_no; - $CashApply->apply_cash = $post['apply_cash'];//申请提现金额 - $CashApply->charge_cash = $shouxufei;//手续费 - $CashApply->true_cash = bcsub($CashApply->apply_cash, $shouxufei, 2);//实际到账金额 + $CashApply->apply_cash = $post['apply_cash']; //申请提现金额 + $CashApply->charge_cash = $shouxufei; //手续费 + $CashApply->true_cash = bcsub($CashApply->apply_cash, $shouxufei, 2); //实际到账金额 $CashApply->apply_time = date('Y-m-d H:i:s', time()); $CashApply->saveOrFail(); + // 记录操作日志 $log = new Log(); $log->admin_id = $user->uid; $log->operate_time = date('Y-m-d H:i:s', time()); $log->type = '平台申请打款'; $log->content = '平台ID:' . $user->uid . '申请打款:' . $post['apply_cash'] . '元,订单号为::' . $order_no . ',开户人姓名为:' . $post['bank_user_name'] . ',银行卡号:' . $post['bank_card'] . ',开户行名称:' . $post['bank_name'] . ',银行账户类型:' . $post['bank_account_type'] . ',账户冻结金额由原来的:' . $Account->frozen_cash . '元变为:' . $CashAccount->frozen_cash . '元'; - $log->mold = 3;//财务操作 + $log->mold = 3; //财务操作 $log->save(); + // 更新日志记录 \Yii::$app->db->createCommand()->update('yii_log', ['content' => Json::encode($log->attributes)], ['id' => $log->attributes['id']])->execute(); + // 提交事务 $t->commit(); return ['申请成功']; } catch (\Exception $e) { + // 回滚事务 $t->rollBack(); throw new Exception($e->getMessage()); } @@ -221,13 +245,21 @@ class DivideAccountController extends BaseAdminController */ public function actionApplyAgree() { + // 获取前端传递的POST数据 $post = \Yii::$app->request->post(); + + // 对POST数据进行验证,确保必要的字段不为空 $this->requestValidate($post, [ [['id', 'check_result', 'user_type'], 'required'], ]); + + // 获取当前用户身份 $user = \Yii::$app->user->identity; + + // 检查用户角色,如果不是超级管理员,则抛出异常 if ($user->role != UserRoleEnum::SUPER_ADMIN) throw new Exception('你不是超级管理员,没有分账申请打款审核权限'); + // 根据POST数据查找现金申请信息,确保该申请存在且待审核 $CashApply = CashApply::find()->where([ 'id' => $post['id'], 'user_type' => $post['user_type'], @@ -235,127 +267,152 @@ class DivideAccountController extends BaseAdminController ])->one(); if (!$CashApply) throw new Exception('申请不存在'); - if ($post['user_type'] == 1) {//诊所 + // 根据用户类型(诊所或平台)查找对应的账户信息和配置 + if ($post['user_type'] == 1) { // 诊所 $Account = CashAccount::find()->where([ 'user_id' => $CashApply->user_id, 'user_type' => $CashApply->user_type ])->one(); - $config=Store::find()->where(['id'=>$CashApply->user_id])->one(); - } else {//平台 + $config = Store::find()->where(['id' => $CashApply->user_id])->one(); + } else { // 平台 $Account = CashAccount::find()->where([ 'user_id' => 0, 'user_type' => $CashApply->user_type ])->one(); - $config=Admin::find()->where(['role'=>UserRoleEnum::SUPER_ADMIN])->one(); + $config = Admin::find()->where(['role' => UserRoleEnum::SUPER_ADMIN])->one(); } + // 确保诊所或平台的账号存在 if (!$Account) throw new Exception('诊所或平台的账号不存在'); + // 再次确认现金账户信息 $CashAccount = CashAccount::find()->where([ 'user_type' => $CashApply->user_type, 'user_id' => $CashApply->user_id ])->one(); - if (empty($config['bank_user_name']) || empty($config['bank_card']) || empty($config['bank_name']) || empty($config['bank_account_type'])){ - $CashAccount->frozen_cash = bcsub($CashAccount->frozen_cash, $CashApply->apply_cash, 2);//申请提现冻结的金额 + // 检查银行账户配置是否完整,如果有任一配置项为空,则解冻申请提现的金额,并记录审核失败 + if (empty($config['bank_user_name']) || empty($config['bank_card']) || empty($config['bank_name']) || empty($config['bank_account_type'])) { + $CashAccount->frozen_cash = bcsub($CashAccount->frozen_cash, $CashApply->apply_cash, 2); // 申请提现冻结的金额 $CashAccount->saveOrFail(); $CashApply->check_id = $user->uid; - $CashApply->check_status = 4;//提现失败 + $CashApply->check_status = 4; // 提现失败 $CashApply->check_result = '银行卡相关配置不完善'; $CashApply->check_time = date('Y-m-d H:i:s', time()); - $CashApply->dakuan_status = -1;//失败 + $CashApply->dakuan_status = -1; // 失败 $CashApply->dakuan_time = date('Y-m-d H:i:s', time()); $CashApply->saveOrFail(); + // 创建日志记录,记录此次审核操作的详细信息 $log = new Log(); $log->admin_id = $user->uid; $log->operate_time = date('Y-m-d H:i:s', time()); $log->type = '分账申请打款审核'; - $log->content = '超级管理员:' . $user->uid . '打款操作,订单号:' . $CashApply->order_no . ',打款金额:' . bcadd($CashApply->true_cash,2,2) . '元,开户人姓名:' . $config->bank_user_name . ',银行卡号:' . $config->bank_card . ',银行名称:' . $config->bank_name . ',银行账户类型:' . $config->bank_account_type . ',打款失败,原因:银行卡相关配置不完善' ; - $log->mold = 3;//财务操作 + // TODO 暂时关闭手续费 +// $log->content = '超级管理员:' . $user->uid . '打款操作,订单号:' . $CashApply->order_no . ',打款金额:' . bcadd($CashApply->true_cash, 2, 2) . '元,开户人姓名:' . $config->bank_user_name . ',银行卡号:' . $config->bank_card . ',银行名称:' . $config->bank_name . ',银行账户类型:' . $config->bank_account_type . ',打款失败,原因:银行卡相关配置不完善'; + $log->content = '超级管理员:' . $user->uid . '打款操作,订单号:' . $CashApply->order_no . ',打款金额:' . $CashApply->true_cash . '元,开户人姓名:' . $config->bank_user_name . ',银行卡号:' . $config->bank_card . ',银行名称:' . $config->bank_name . ',银行账户类型:' . $config->bank_account_type . ',打款失败,原因:银行卡相关配置不完善'; + $log->mold = 3; // 财务操作 $log->saveOrFail(); + // 更新日志内容到数据库 \Yii::$app->db->createCommand()->update('yii_log', ['content' => Json::encode($log->attributes)], ['id' => $log->attributes['id']])->execute(); throw new \yii\db\Exception('银行卡相关配置不能为空'); } - $param=[ - 'order_no'=>$CashApply->order_no, - 'apply_cash'=>bcadd($CashApply->true_cash,1,2), - 'bank_name'=>$config->bank_name, - 'bank_account_type'=>$config->bank_account_type, - 'bank_no'=>$config->bank_no, - 'bank_user_name' => $config->bank_user_name, - 'bank_card' => $config->bank_card, + // 准备打款参数 + $param = [ + 'order_no' => $CashApply->order_no, // 订单号 + 'apply_cash' => bcadd($CashApply->true_cash, 1, 2), // 实际打款金额 1元是银联手续费 + 'bank_name' => $config->bank_name, // 银行名称 + 'bank_account_type' => $config->bank_account_type, // 银行账户类型 + 'bank_no' => $config->bank_no, // 银行账号 + 'bank_user_name' => $config->bank_user_name, // 开户人姓名 + 'bank_card' => $config->bank_card, // 银行卡号 ]; - //打款 - $res = EplPayService::getInstance()->withDraw($param); - //打款失败 - if ($res['returnCode'] != 0000) { - try { - $transaction=\Yii::$app->db->beginTransaction(); - $CashAccount->frozen_cash = bcsub($CashAccount->frozen_cash, $CashApply->apply_cash, 2);//申请提现冻结的金额 + // 执行打款操作 + $res = EplPayService::getInstance()->withDraw($param); + + // 处理打款失败情况 + if ($res['returnCode'] != '0000') { + try { + // 开始事务 + $transaction = \Yii::$app->db->beginTransaction(); + + // 更新用户账户信息,解冻申请提现的金额 + $CashAccount->frozen_cash = bcsub($CashAccount->frozen_cash, $CashApply->apply_cash, 2); $CashAccount->saveOrFail(); + // 更新提现申请状态为失败 $CashApply->check_id = $user->uid; - $CashApply->check_status = 4;//提现失败 + $CashApply->check_status = 4; // 提现失败状态码 $CashApply->check_result = $res['returnMsg']; $CashApply->check_time = date('Y-m-d H:i:s', time()); - $CashApply->dakuan_status = -1;//失败 + $CashApply->dakuan_status = -1; // 打款失败状态码 $CashApply->dakuan_time = date('Y-m-d H:i:s', time()); $CashApply->saveOrFail(); + // 记录日志 $log = new Log(); $log->admin_id = $user->uid; $log->operate_time = date('Y-m-d H:i:s', time()); $log->type = '分账申请打款审核'; - $log->content = '打款失败:超级管理员:' . $user->uid . '打款操作,订单号:' . $CashApply->order_no . ',打款金额:' . bcadd($CashApply->true_cash,2,2) . '元,开户人姓名:' . $config->bank_user_name . ',银行卡号:' . $config->bank_card . ',银行名称:' . $config->bank_name . ',银行账户类型:' . $config->bank_account_type . ',打款失败,原因:' . $res['returnMsg']; - $log->mold = 3;//财务操作 + // TODO 暂时关闭手续费 +// $log->content = '打款失败:超级管理员:' . $user->uid . '打款操作,订单号:' . $CashApply->order_no . ',打款金额:' . bcadd($CashApply->true_cash, 2, 2) . '元,开户人姓名:' . $config->bank_user_name . ',银行卡号:' . $config->bank_card . ',银行名称:' . $config->bank_name . ',银行账户类型:' . $config->bank_account_type . ',打款失败,原因:' . $res['returnMsg']; + $log->content = '打款失败:超级管理员:' . $user->uid . '打款操作,订单号:' . $CashApply->order_no . ',打款金额:' . $CashApply->true_cash . '元,开户人姓名:' . $config->bank_user_name . ',银行卡号:' . $config->bank_card . ',银行名称:' . $config->bank_name . ',银行账户类型:' . $config->bank_account_type . ',打款失败,原因:' . $res['returnMsg']; + $log->mold = 3; // 财务操作状态码 $log->saveOrFail(); + // 更新日志表内容 \Yii::$app->db->createCommand()->update('yii_log', ['content' => Json::encode($log->attributes)], ['id' => $log->attributes['id']])->execute(); + // 提交事务 $transaction->commit(); return $res; - }catch (\Exception $e){ + } catch (\Exception $e) { + // 回滚事务 $transaction->rollBack(); throw new \yii\db\Exception($e->getMessage()); } - }else{ + } else { + // 处理打款成功情况 $t = \Yii::$app->db->beginTransaction(); try { - //打款成功 - $CashAccount->able_cash = bcsub($CashAccount->able_cash, $CashApply->apply_cash, 2);//账户余额 - $CashAccount->frozen_cash = bcsub($CashAccount->frozen_cash, $CashApply->apply_cash, 2);//申请提现冻结的金额 - $CashAccount->withdrawn_cash = bcadd($CashAccount->withdrawn_cash, $CashApply->true_cash, 2);//已提现金额 - $CashAccount->charge_cash = bcadd($CashAccount->charge_cash, $CashApply->charge_cash, 2);//手续费 + // 更新用户账户信息,扣除账户余额,解冻申请提现的金额,增加已提现金额和手续费 + $CashAccount->able_cash = bcsub($CashAccount->able_cash, $CashApply->apply_cash, 2); + $CashAccount->frozen_cash = bcsub($CashAccount->frozen_cash, $CashApply->apply_cash, 2); + $CashAccount->withdrawn_cash = bcadd($CashAccount->withdrawn_cash, $CashApply->true_cash, 2); + $CashAccount->charge_cash = bcadd($CashAccount->charge_cash, $CashApply->charge_cash, 2); $CashAccount->saveOrFail(); + // 更新提现申请状态为成功 $CashApply->check_id = $user->uid; - $CashApply->check_status = 2;//成功 + $CashApply->check_status = 2; // 提现成功状态码 $CashApply->check_result = $post['check_result']; $CashApply->check_time = date('Y-m-d H:i:s', time()); - $CashApply->check_time = date('Y-m-d H:i:s', time()); - $CashApply->dakuan_status = 1;//成功 + $CashApply->dakuan_status = 1; // 打款成功状态码 $CashApply->dakuan_time = date('Y-m-d H:i:s', time()); $CashApply->saveOrFail(); + // 记录日志 $log = new Log(); $log->admin_id = $user->uid; $log->operate_time = date('Y-m-d H:i:s', time()); $log->type = '分账申请打款审核'; $log->content = $user->uid . '通过了ID为:' . $post['id'] . '的打款申请,打款结果:成功'; - $log->mold = 3;//财务操作 + $log->mold = 3; // 财务操作状态码 $log->save(); + // 更新日志表内容 \Yii::$app->db->createCommand()->update('yii_log', ['content' => Json::encode($log->attributes)], ['id' => $log->attributes['id']])->execute(); + // 提交事务 $t->commit(); return ['审核成功']; } catch (\Exception $e) { + // 回滚事务 $t->rollBack(); throw new Exception($e->getMessage()); } diff --git a/common/services/EplPayService.php b/common/services/EplPayService.php index a45b987..060515b 100644 --- a/common/services/EplPayService.php +++ b/common/services/EplPayService.php @@ -117,30 +117,54 @@ class EplPayService //单笔提现 public function withDraw($params){ + // 构建请求提现接口的URL $url = $this->eplConfig['url'].'/api/txs/pay/withdrawalToCard'; + + // 构建请求参数数组 $param = [ + // 设置商户订单号 'outTradeNo' => $params['order_no'], + // 设置客户代码 'customerCode' => $this->eplConfig['customerCode'], + // 设置提现金额,将申请的现金金额乘以100,转换为分 'amount' => bcmul($params['apply_cash'], 100, 0), - 'arrivalType' => 0,// 到账类型 0当日 1次日 最大99 - 'procedureType' => 'inner', //inner内扣 outer外扣 - 'bankUserName' => $this->public_encrypt($params['bank_user_name']), //开户人姓名 - 'bankCardNo' => $this->public_encrypt($params['bank_card']), //银行卡号 - 'bankName' => $params['bank_name'],// 银行名称 - 'bankAccountType' => $params['bank_account_type'], //1对公 2对私 5存折 + // 设置到账类型,0表示当日到账 + 'arrivalType' => 0, + // 设置手续费扣除方式,内扣或外扣 + 'procedureType' => 'inner', + // 设置开户人姓名,使用公钥加密 + 'bankUserName' => $this->public_encrypt($params['bank_user_name']), + // 设置银行卡号,使用公钥加密 + 'bankCardNo' => $this->public_encrypt($params['bank_card']), + // 设置银行名称 + 'bankName' => $params['bank_name'], + // 设置账户类型,对公、对私或存折 + 'bankAccountType' => $params['bank_account_type'], + // 设置服务器回调通知URL 'notifyUrl' => $this->eplConfig['withdraw_notify_url'], + // 设置支付货币类型 'payCurrency' => 'CNY', + // 设置随机字符串 'nonceStr' => FuncHelper::uuid() ]; + + // 根据银行账户类型和银行卡号的前两位判断是否需要设置银行代码 if($params['bank_account_type'] != '2' || substr($params['bank_card'],0,2) != '62'){ $param['bankNo'] = $params['bank_no']; } + // 生成请求的签名 $sign = $this->sign(Json::encode($param)); + + // 发起提现请求 $result = $this->http_post_json($url,Json::encode($param),$sign); + + // 验证请求结果,如果结果为空或HTTP状态码不是200,则抛出异常 if(!$result || $result[0] != 200){ throw new Exception('提现失败'); } + + // 解析并返回提现请求的结果 return Json::decode($result[1]); }