RechargePackageService.php 6.0 KB
<?php
/**
+-----------------------------------------------------------------------------------------------------------------------
 * 逻辑层:RechargePackage 服务类,处理业务逻辑
+-----------------------------------------------------------------------------------------------------------------------
 *
 * PHP version 7
 *
 * @category  App\Services
 * @package   App\Services
 * @author    Richer <yangzi1028@163.com>
 * @date      2023年4月23日11:21:31
 * @copyright 2021-2022 Richer (http://www.Richer.com/)
 * @license   http://www.Richer.com/ License
 * @link      http://www.Richer.com/
 */
namespace App\Services;

use App\Models\RechargeOrder;
use App\Models\RechargePackage;
use Illuminate\Support\Facades\DB;
use Yansongda\LaravelPay\Facades\Pay;

/**
 * Class RechargePackageService
 * @package App\Services
 */
class RechargePackageService extends BaseService
{
    /**
     * RechargePackageService constructor.
     *
     * @param RechargePackage $model
     */
    public function __construct(RechargePackage $model)
    {
         // 执行父类构造方法
        parent::__construct($model);
    }

    /**
     * Display a listing of the resource.
     *
     * @return array|\Illuminate\Contracts\Pagination\LengthAwarePaginator|\Illuminate\Support\Collection
     */
    public function list()
    {
        return $this->model
        ->when($q = request('name'), function ($query) use ($q) {
            $query->where("name", 'like', "%$q%");
        })->latest()->get();
    }

    /**
     * Display the specified resource.
     *
     * @param int $id 主键id
     * @param array $columns 列
     *
     * @return array|bool|\Illuminate\Support\Collection
     */
    public function show($id, $columns = ['*'])
    {
        $sort = request('sort', 'asc');
        $model = $this->model->with(['location','route.sites' => function ($query) use ($sort) {
            $query->with(['site'])->orderBy('sort', $sort);
//            $query->with(['route' => function ($query) use ($sort)  {
//                $query->with(['site'])->orderBy('sort', $sort);
//            }])->orderBy('sort', $sort);
        }])->findOrFail($id);
        $model->function = 'show';
        return $model;
    }

    /**
     * 充值
     *
     * @param $request
     */
    public function recharge($request, $id)
    {
        $user = $this->getLoginUser();
        DB::beginTransaction();
        try {
            $model = $this->model->findOrFail($id);
            $quantity = $request->quantity;
            $price = $model->price;
            $amount =  $quantity * $price;
            $order = $model->orders()->create(
                [
                    'user_id'   => $user->id,
                    'number'    => generate_unique_number(),
                    'quantity'  => $quantity,
                    'amount'    => $amount,
                    'package_info' => $model,
                    'status' => RechargeOrder::UNPAID
                ]
            );

            $out_trade_no = $model->number.time();

            $body = config('app.name_zh');

            // 设置提交请求
            $pay = [
                'out_trade_no' => $out_trade_no
            ];

            // 自定义回调地址
//            if ($notify_url) {
//                $pay['notify_url'] = $notify_url;
//            }
            // 更新订单
            $type = RechargeOrder::H5_PAY;
            $order->out_trade_no = $out_trade_no;
            $model->paid_type = $type;
            $order->save();
            // 唤起支付
            $response = $this->payByWechat($user, $order, $body, $type, $pay);
            if (!$response) {
                return false;
            }

            //提交事务
            DB::commit();

            return [
                'order'     => $order,
                'pay_info'  => $response
            ];

        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            DB::rollBack();
            return false;
        }
    }

    /**
     * 微信支付
     *
     * @param $user
     * @param $model
     * @param $type
     * @param $body
     * @param $pay
     *
     * @return false|mixed|\Yansongda\Supports\Collection
     */
    protected function payByWechat($user, $model, $body, $type, $pay)
    {
        // 获取支付金额
        $total_fee = $this->getPaidAmount($model->amount);

        // 微信支付设置为total_fee 和 body
        // 微信支付提交的金额是不能带小数点的,且是以分为单位,所以我们系统如果是以元为单位要处理下金额,即先乘以100,再去小数点
        // (Math.Round((decimal)order.Amount * 100, 0)).ToString()
        $pay['total_fee'] = $total_fee * 100;// 订单金额,**单位:分**
        $pay['body'] = $body;// 订单描述
        $pay['openid'] = $user->openid ? : request('openid');// 支付人的 openID
        $pay['spbill_create_ip'] = request()->ip();// 支付人的 IP

        // 微信支付
        try {
            $response = null;
            switch ($type) {
                case RechargeOrder::WECHAT_PAY:// 微信支付
                    $response = Pay::wechat()->miniapp($pay);
                    break;
                case RechargeOrder::H5_PAY:// H5
                    $response = Pay::wechat()->mp($pay);
                    break;
            }
            return $response;
        } catch (\Exception $e) {
            $replace = ['ERROR_GATEWAY: Get Wechat API Error:', 'ERROR_GATEWAY: ERROR_BUSINESS: Wechat Business Error: '];
            $this->message = '支付失败,' . str_replace($replace, '', $e->getMessage());
            return false;
        }
    }

    /**
     * 获取支付金额:在非生产试环境中,将支付金额设置为0.01,方便测试环境进行支付测试
     *
     * @param float $amount 金额
     *
     * @return float
     */
    protected function getPaidAmount($amount)
    {
        // 测试环境和本地环境支付金额为0.01
        if (config('app.env') !== 'production') {
            $amount = 0.01;
        }


        return $amount;
    }

}