123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- <?php
- // +----------------------------------------------------------------------
- // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
- // +----------------------------------------------------------------------
- // | Author: 萤火科技 <admin@yiovo.com>
- // +----------------------------------------------------------------------
- declare (strict_types=1);
- namespace app\store\controller\user;
- use app\common\library\helper;
- use app\common\library\wechat\WxPay;
- use app\common\model\user\UserIdcards;
- use app\store\controller\Controller;
- use app\store\model\User as UserModel;
- use app\store\model\user\Withdraw as WithdrawModel;
- use think\cache\driver\Redis;
- use app\store\model\Wxapp as WxappModel;
- use app\api\model\User as UserApiModel;
- use app\common\service\Export as ExportService;
- use app\common\enum\order\orderGoods\ExportStatus as ExportStatusEnum;
- /**
- * 用户提现
- * Class Withdraw
- * @package app\store\controller\user
- */
- class Withdraw extends Controller
- {
- public function list()
- {
- $params = $this->request->param();
- $model = new WithdrawModel;
- $list = $model->getList($params);
- return $this->renderSuccess(compact('list'));
- }
- /**
- * 提现列表导出功能
- * @return array
- * @author: zq
- * @Time: 2022/2/22 10:43
- */
- public function orderExport(){
- $param = $this->request->param();
- /* if(isset($param['id']) && empty($param['id'])){
- return $this->renderError('请勾选订单商品后再导出');
- }*/
- $model = new WithdrawModel();
- $data = $model->listExport($param);
- $res = ExportService::export($data['data'],$data['header'],$data['filename'],'列表','Xls');
- return $this->renderSuccess($res,'导出成功');
- }
- public function dataCount()
- {
- $arr = [];
- $arr['all_num'] = WithdrawModel::count();
- $arr['audit_0'] = WithdrawModel::where("audit", 0)->count();
- $arr['audit_1'] = WithdrawModel::where("audit", 1)->count();
- $arr['audit_2'] = $arr['all_num'] - $arr['audit_0'] - $arr['audit_1'];
- $arr['pay_state_0'] = WithdrawModel::where("pay_state", 0)->count();
- $arr['pay_state_1'] = WithdrawModel::where("pay_state", 1)->count();
- $arr['pay_state_2'] = WithdrawModel::where("pay_state", 2)->count();
- $arr['pay_state_3'] = WithdrawModel::where("pay_state", 3)->count();
- return $this->renderSuccess(compact('arr'));
- }
- public function detail($id = 0)
- {
- $detail = WithdrawModel::with(['user'])->where('id', $id)->find();
- if (empty($detail)) {
- return $this->renderError('参数无效');
- }
- $detail->user->promote_user_count = UserApiModel::countSubordinates($detail->user_id, $detail->shop_id, $detail->role); // 直推人数
- $detail->user->promote_user_name = UserModel::where('user_id',$detail->user->upper_user_id)->value('nick_name') ?? '';
- $detail->user->idcard = UserIdcards::where('user_id',$detail->user_id)->field('real_name')->find() ?? '';
- return $this->renderSuccess(compact('detail'));
- }
- //审核
- public function audit(int $id)
- {
- $params = $this->postForm();
- $detail = WithdrawModel::with(['user'])->where('id', $id)->find();
- if (empty($detail)) {
- return $this->renderError('参数无效');
- }
- $user = $detail->user;
- if ($detail->audit == 0 && $params['audit'] != $detail->audit) {
- $detail->audit = $params['audit'];
- $detail->audit_remark = $params['audit_remark'] ?? '';
- $detail->audit_time = date("Y-m-d H:i:s");
- $detail->save();
- if ($detail->audit == 2) {
- $user->ktxyj_amount += $detail->amount;//转账失败返回提现金额给用户
- $user->frozen_yj_amount -= $detail->amount;//转账失败从冻结金额中扣除单笔提现金额
- $user->save();
- }
- // if ($audit == 2) {
- //// $user->wjsyj_amount = $user->wjsyj_amount - $detail->amount;
- //// $user->save();
- // $title = '审核不通过';
- // $content = '非常抱歉,您的提现申请审核不通过.原因:' . $audit_remark;
- // } else {
- // $title = '审核通过';
- // $content = '恭喜您,您的提现申请已通过,工作人员将尽快为您打款,请留意支付宝信息。';
- // }
- // $ids = $detail->user_id;
- // $url = config('chef.serv_cookhome') . '/api/shop_pushes?title=' . $title . '&content=' . $content . '&ids=' . $ids . '&url=' . urlencode('zd://chefPush?target=shop_push_my_withdrawal&id=' . $id);
- // helper::curlRequest($url);
- return $this->renderSuccess('审核成功');
- } else {
- return $this->renderError('已经审核过了');
- }
- }
- //去支付
- public function topay($id)
- {
- $params = $this->postForm();
- $detail = WithdrawModel::with(['user'])->where('id', $id)->find();
- $user = $detail->user;
- if ($detail->pay_state == 1) {
- return $this->renderError("已支付,请勿重复付款");
- }
- if ($detail->pay_state == 3) {
- return $this->renderError("打款中,请勿重复付款");
- }
- if ($detail->audit != 1) {
- return $this->renderError("未审核通过,不能付款");
- }
- $pay_amount = helper::bcsub($detail->amount, $detail->tax, 2);
- if ($detail['transaction_type'] == 1) {
- // 支付宝提现
- $ret = $this->aliWithdrawal($detail, $pay_amount);
- $pay_type = 1;
- } elseif ($detail['transaction_type'] == 2) {
- // 微信提现
- $params['remark'] = $params['remark'] ?: '佣金提现'; // 默认打款备注信息
- $ret = $this->wxWithdrawal($detail, $pay_amount, $params['remark']);
- $pay_type = 2;
- } else {
- return $this->renderError('提现方式不正确');
- }
-
- $storeInfo = $this->store;
- if ($ret['code'] == 1) {
- $detail->remark = $params['remark'];
- $detail->pay_state = 1;
- $detail->pay_type = $pay_type;
- $detail->pay_time = date("Y-m-d H:i:s");
- $detail->pay_transaction_no = $ret['pay_transaction_no'];
- //微信或支付宝支付流水号,暂时只记录了微信的流水号,支付宝流水号没保存20220413
- $detail->third_trans_no = $ret['payment_no']??'';
- $detail->admin_id = $storeInfo['user']['store_user_id'];
- $detail->pay_amount = $pay_amount;
- $user->frozen_yj_amount -= $detail->amount;//提现成功从冻结金额中扣除单笔提现金额
- $user->have_withdrew_money += $detail->amount;
- $user->save();
- $detail->save();
- return $this->renderSuccess('付款成功');
- } else {
- $reason = $ret['reason'];
- $detail->not_pass_resaon = $reason;
- $detail->pay_state = $pay_type;
- $detail->admin_id = $storeInfo['user']['store_user_id'];
- $user->ktxyj_amount += $detail->amount;//转账失败返回提现金额给用户
- $user->frozen_yj_amount -= $detail->amount;//转账失败从冻结金额中扣除单笔提现金额
- $user->save();
- $detail->save();
- return $this->renderError($reason ?? '付款失败');
- }
- }
- /**
- * 支付宝提现
- * @param object $detail 提现申请信息
- * @param string $pay_amount 付款金额
- * @return array
- */
- private function aliWithdrawal($detail, $pay_amount) {
- $redis = new Redis(config('cache.stores.redis'));
- $redis->set('fx_pay_' . $detail->user_id, 1, 600);
- $url = config('chef.serv_cookhome') . '/api/shop/pay_ali_account?account=' . $detail->tx_account . '&amount=' . $pay_amount . '&real_name=' . $detail->real_name . "&user_id=" . $detail->user_id;
- $res = helper::curlRequest($url);
- $arr = json_decode($res, true);
- if ($arr['ret'] == 1) {
- return ['code' => 1, 'msg' => '付款成功', 'pay_transaction_no' => $arr['order_no']];
- } else {
- return ['code' => 0, 'msg' => '付款失败', 'reason' => $arr['reason']];
- }
- }
- /**
- * 小程序提现
- * todo 定时任务轮询打款中状态的提现订单,
- * 调用微信查询订单接口,直到返回打款成功,
- * 才将状态改为已打款,并更新用户账号资金。
- *
- * @param object $detail 提现申请信息
- * @param string $pay_amount 付款金额
- * @return array
- */
- private function wxWithdrawal($detail, $pay_amount, $remark = '') {
- // 验证限制
- $this->checkPayLimit($detail->user_id, $pay_amount);
- $orderNo = WithdrawModel::makePayTransactionNo();
- $user = $detail->user;
- $wxPay = new WxPay(static::getWxConfig());
- $res = $wxPay->transfers($orderNo, $user->open_id, $pay_amount, $remark);
- // if ($res === true) {
- if (isset($res['status']) && $res['status'] === true) {
- //todo 先注释掉测试一下提现20220412,感觉像之前遗留的多余的一行代码
- //$wxPay->transfers($orderNo, $user->open_id, $pay_amount, $remark);
- return ['code' => 1, 'msg' => '付款成功', 'pay_transaction_no' => $orderNo,'payment_no'=>$res['payment_no']];
- } else {
- // 判断各种失败状态
- // 当返回错误码为“SYSTEMERROR”时,请不要更换商户订单号,一定要使用原商户订单号重试,否则可能造成重复支付等资金风险。
- if ($res['data']['err_code'] == 'SYSTEMERROR') { // 将当前提现单状态改为打款中,然后后台操作人可以重复进行打款操作,直到成功为止。
- $detail->pay_state = 3; // 3-打款中
- $detail->admin_id = $this->store['user']['store_user_id'];
- $detail->pay_transaction_no = $orderNo;
- $detail->save();
- return $this->renderError('付款失败,请稍后重试');
- }
- return ['code' => 0, 'msg' => $res['msg'] ?? '付款失败', 'reason' => $res['msg']];
- }
- }
- /**
- * 尝试重试打款
- * 用同一个商户订单号向微信发起打款请求
- * 当打款成功时
- */
- public function repay($id) {
- $params = $this->postForm();
- $detail = WithdrawModel::with(['user'])->where('id', $id)->find();
- $user = $detail->user;
- if ($detail->pay_state != 3) {
- return $this->renderError("非打款中状态,请问重复付款");
- }
- if ($detail->audit != 1) {
- return $this->renderError("未审核通过,不能付款");
- }
- $pay_amount = helper::bcsub($detail->amount, $detail->tax, 2);
- if ($detail['transaction_type'] == 1) {
- // 支付宝提现
- $pay_type = 1;
- } elseif ($detail['transaction_type'] == 2) {
- // 微信提现
- $ret = $this->wxRepay($detail, $pay_amount, $params['remark']);
- $pay_type = 2;
- } else {
- return $this->renderError('提现方式不正确');
- }
-
- $storeInfo = $this->store;
- if ($ret['code'] == 1) {
- $detail->remark = $params['remark'];
- $detail->pay_state = 1;
- $detail->pay_type = $pay_type;
- $detail->pay_time = date("Y-m-d H:i:s");
- $detail->pay_transaction_no = $ret['pay_transaction_no'];
- $detail->admin_id = $storeInfo['user']['store_user_id'];
- $detail->pay_amount = $pay_amount;
- $user->frozen_yj_amount -= $detail->amount;//提现成功从冻结金额中扣除单笔提现金额
- $user->have_withdrew_money += $detail->amount;
- $user->save();
- $detail->save();
- return $this->renderSuccess('付款成功');
- } else {
- return $this->renderError($reason ?? '付款失败');
- }
- }
- /**
- * 微信重试打款
- * todo 请勿付款和查询并发处理
- */
- private function wxRepay($detail, $pay_amount, $remark = '') {
- $orderNo = $detail->pay_transaction_no;
- if (empty($orderNo)) {
- return $this->renderError('提现单异常');
- }
- // 验证限制
- $this->checkPayLimit($detail->user_id, $pay_amount);
- // 查询付款状态
- $wxPay = new WxPay(static::getWxConfig());
- $queryRes = $wxPay->getTransferInfo($orderNo);
- if ($queryRes === true) {
- // 查询结果为付款成功 则更新状态
- return ['code' => 1, 'msg' => '付款成功', 'pay_transaction_no' => $orderNo];
- }
-
- $user = $detail->user;
- $res = $wxPay->transfers($orderNo, $user->open_id, $pay_amount, $remark);
- //if ($res === true) {
- if (isset($res['status']) && $res['status'] === true) {
- //todo 先注释掉测试一下提现20220412,感觉像之前遗留的多余的一行代码
- //$wxPay->transfers($orderNo, $user->open_id, $pay_amount, $remark);
- return ['code' => 1, 'msg' => '付款成功', 'pay_transaction_no' => $orderNo,'payment_no'=>$res['payment_no']];
- } else {
- // 判断各种失败状态
- // 当返回错误码为“SYSTEMERROR”时,请不要更换商户订单号,一定要使用原商户订单号重试,否则可能造成重复支付等资金风险。
- if ($res['data']['err_code'] == 'SYSTEMERROR') {
- return $this->renderError('付款失败,请稍后重试');
- }
- return ['code' => 0, 'msg' => $res['msg'] ?? '付款失败', 'reason' => $res['msg']];
- }
- }
- /**
- * 检查用户提现限制
- */
- private function checkPayLimit($userId, $pay_amount) {
- // 判断用户是否当日提现次数超过10次,大于10次提示“您今日提现过于频繁,请次日再来~”
- $dayCount = WithdrawModel::where('user_id', $userId)
- ->whereTime('pay_time', 'today')
- ->count();
- if ($dayCount > 10) {
- return $this->renderError('您今日提现过于频繁,请次日再来~');
- }
-
- // 判断用户是否当日提现金额超过5000元,当日累计申请提现(含本次)大于5000元时提示“您今日累计提现数值较大,请次日再来~”
- $dayAmount = WithdrawModel::where('user_id', $userId)
- ->whereTime('pay_time', 'today')
- ->sum('pay_amount');
- if ($dayAmount + $pay_amount > 5000) {
- return $this->renderError('您今日累计提现数值较大,请次日再来');
- }
- }
- /**
- * 获取微信支付配置
- * @return array
- * @throws BaseException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- private static function getWxConfig()
- {
- return WxappModel::getWxappCache(getStoreId());
- }
- }
|