6
0
Fork 0
jiqu-library-server/app/Services/VipService.php

151 lines
4.5 KiB
PHP

<?php
namespace App\Services;
use App\Models\{User, Vip, UserVip, PayLog, Coupon};
use App\Exceptions\BizException;
use App\Enums\{PayWay, SocialiteType, WxpayTradeType};
use App\Services\Payment\WxpayService;
use Carbon\Carbon;
class VipService
{
public function buy(User $user, Vip $vip)
{
if (!$vip->status) {
throw new BizException('该会员卡已关闭');
}
$user_vip = $user->vips()->create([
'vip_id' => $vip->id,
'name' => $vip->name,
'price' => $vip->price,
'times' => $vip->times,
'gift' => $vip->gift,
]);
return $user_vip;
}
public function pay(UserVip $userVip, $pay_way = '')
{
if (!$pay_way) {
$pay_way = PayWay::WxpayMiniProgram->value;
}
if ($userVip->status == 2) {
throw new BizException('支付处理中,请勿重复操作');
}
$userVip->update([
'status' => 2
]);
$pay_log = $userVip->pay()->create([
'pay_sn' => serial_number(),
'pay_way' => $pay_way
]);
$money = $userVip->price;
$debug = config('app.debug');
if ($debug) {
$money = 0.01;
}
$user = $userVip->user;
// 微信小程序支付
if ($pay_log->pay_way === PayWay::WxpayMiniProgram) {
$openid = $user->socialites()->where('socialite_type', SocialiteType::WechatMiniProgram)->value('socialite_id');
if (!$openid && $debug) {
$openid = 'oU7xS5UspzVvpPEBqKZuW6N9WXDg';
}
if (!$openid) {
throw new BizException('未找到用户的微信授权信息, 无法使用微信支付');
}
$params = [
'body' => app_settings('app.app_name').'-会员-' . $userVip->name,
'out_trade_no' => $pay_log->pay_sn,
'total_fee' => $money * 100,
'trade_type' => WxpayTradeType::JSAPI->value,
'openid' => $openid,
];
return ['pay_way' => $pay_way, 'data' => (new WxpayService())->pay($params)];
}
throw new BizException('未知的支付方式');
}
/**
* 购买成功
* @param UserVip $userVip 购买记录
* @param array $params {'pay_at':'购买时间'}
*/
public function success(UserVip $userVip, array $params = null)
{
$userVip->update([
'status' => 1,
'success_time' => data_get($params, 'pay_at', now())
]);
$user = $userVip->user;
$vip_expired = $this->convertTimes(data_get($userVip->times, 'num'), data_get($userVip->times, 'unit'), $user->vip_expired);
$userVip->update([
'expired' => $vip_expired
]);
$userVip->user->update([
'vip_expired' => $vip_expired
]);
$this->gift($userVip);
}
/**
* 发放赠品
* @param UserVip $userVip 购买记录
*/
public function gift(UserVip $userVip)
{
if ($userVip->status != 1) {
throw new BizException('请先购买');
}
$user = $userVip->user;
$gift = $userVip->gift;
// 优惠券
if (isset($gift['coupon']) && $gift['coupon']) {
$coupon_service = new CouponService();
$couponId = array_column($gift['coupon'], 'id');
foreach(Coupon::whereIn('id', $couponId)->get() as $item) {
try {
$couponItem = array_filter($gift['coupon'], fn($v) => $v['id'] == $item->id);
$amount = data_get($couponItem, 'amount', 1);
if ($amount > 0) {
$coupon_service->sendCoupon($user, $item, $amount);
}
} catch (BizException $e) {
}
}
}
}
/**
* 延长时限
*
* @param int $num 数量
* @param string $unit 单位
* @return Carbon
*/
public function convertTimes(int $num, string $unit, Carbon $start = null)
{
if (!$start) {
$start = now();
}
switch ($unit) {
case Vip::TIME_YEAR:
$start->addYears($num);
break;
case Vip::TIME_MONTH:
$start->addMonths($num);
break;
case Vip::TIME_DAY:
$start->addDays($num);
break;
default:
throw new BizException('未知的时间单位');
}
return $start;
}
}