|
|
<?php
namespace App\Service;
use Hyperf\Di\Annotation\Inject;use Hyperf\DbConnection\Db;use App\Model\CouponUserRecType;use App\Model\Coupon;use App\Model\CouponRec;use App\Model\CouponUserUse;use Hyperf\Utils\ApplicationContext;use App\TaskWorker\SSDBTask;use App\Constants\SsdbKeysPrefix;use App\Constants\LogLabel;use App\Commons\Log;use Exception;use App\Service\CommonService;use Hyperf\Redis\Redis;
class CouponService implements CouponServiceInterface{ /** * @Inject * @var Log */ protected $log; /** * @Inject * @var CommonService */ protected $commonService;
/** * 获取用户可领取优惠卷接口 */ public function getSystemCouponUserList($userId,$receiveType) { /* 优惠券活动标志 2 */ $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); $couponActivity = $ssdb->exec('hgetall', SsdbKeysPrefix::COUPON_REBATE_ACTIVITY); $activityType = $couponActivity === false ? 0 : $couponActivity['activity'];
$result = [ 'active_type' => 1, 'not_receive' => [], 'jump_data' => [ 'src' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType, 'src2' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType, 'share_bg' => env('OSS_IMG_HOST').'/static/img/coupon_share.png', 'receive_bg' => env('OSS_IMG_HOST').'/static/img/coupon_bg.png', 'coupons' => [] ] ]; $nowTime = time(); $c_ids = []; $whereC = [ ['end_time','>',$nowTime], ['start_time','<=',$nowTime], ['status','=',1] ]; // 渠道开启,查询该渠道可以领取的优惠券ID
// 渠道未开启,查询所有优惠券
if (env('SUB_CHANNEL') == 1) { $c_ids = CouponUserRecType::where('receive_type', $receiveType)->where($whereC)->pluck('system_coupon_user_id'); } else { $c_ids = Coupon::where($whereC)->pluck('id'); }
$couponReceive = CouponRec::where('user_id',$userId);
// 渠道开启,查询该用户在此渠道领过的优惠券ID
if (env('SUB_CHANNEL') == 1) { $couponReceive->where('receive_type', $receiveType); } $cr_ids = $couponReceive->pluck('system_coupon_user_id');
// 可领取的券ID
$c_ids = $c_ids->toArray(); // 已经领取的券ID
$cr_ids = $cr_ids->toArray();
// 当前用户可领的优惠券ID
$couponIds = array_diff($c_ids, $cr_ids);
// 转发型优惠券
$couponReceiveIds = ($couponActivity === false || $this->commonService->empty($couponActivity['forward']) )? [] : explode(',',$couponActivity['forward']); // 所有优惠券
$couponIds = array_merge($couponIds,$couponReceiveIds);
$whereC = [ ['u.end_time','>',$nowTime], ['u.start_time','<=',$nowTime], ['u.status','=',1] ]; // 查询领取型1 和 转发型2
$whereActiveType = [1,2];
if (env('SUB_CHANNEL') == 1) { array_push($whereC, ['type.receive_type','=', $receiveType]); } $coupons = Db::table('ims_system_coupon_user as u') ->join('ims_system_coupon_user_receivetype as type', 'u.id', '=', 'type.system_coupon_user_id') ->whereIn('u.id', $couponIds) ->whereIn('u.active_type', $whereActiveType) ->where($whereC) ->whereRaw('u.inventory_use < u.inventory and u.inventory-u.inventory_use >= type.one_receive_number') ->select('u.*','type.one_receive_number') ->orderBy('u.weigh','desc') ->get();
foreach ($coupons as $k => &$v){
if($v->active_type == 1 && count($result['not_receive']) < 4){ $result['not_receive'][] = $v; }else if($v->active_type == 2 && in_array($v->id,$couponReceiveIds)){ $result['jump_data']['coupons'][] = $v->id; }
if($v->discount_type == 2){ $v->discounts = floatval($v->discounts); } }
$result['active_type'] = count($result['jump_data']['coupons']) > 0 ? 2 : $result['active_type'] ;
return $result; }
//统计用户
public function userCouponAccount() {
}
/** * 用户领取优惠卷 */ public function userReceiveCoupon() { }
/** * 获取用户已经领取的优惠卷列表 */ public function getUserReceiveCouponList() {
}
/** * 获取用户当前订单可用的优惠券列表 * 按分类(1订单 等优惠)分组返回 */ public function getUserAvailableCoupons($orderAmount,$userId,$marketId,$type,$storetypeId) { $storetypeIds = explode(',', str_replace(',', ',', $storetypeId));
$available = []; $notAvailable = [];
if ($this->empty($orderAmount) || $this->empty($userId)) { return $this->success([ 'available' => $available, 'not_available' => array_values($notAvailable) ]); }
// 获取用户优惠券
$currentTime = time();
$data = Db::table('ims_system_coupon_user_receive as receive') ->select([ 'receive.id as receive_id', 'receive.user_id', 'receive.number_remain', 'coupon.id', 'coupon.title', 'coupon.full_amount', 'coupon.discounts', 'coupon.usable_start_time', 'coupon.usable_end_time', 'coupon.discount_type' ]) ->join('ims_system_coupon_user as coupon', 'coupon.id', '=', 'receive.system_coupon_user_id') ->where(['receive.user_id' => $userId]) ->whereIn('receive.status', [0,1]) ->where('receive.number_remain', '>', 0) ->whereIn('coupon.type', [1,$type]) ->where('coupon.full_amount', '<=', $orderAmount) ->where('coupon.usable_start_time', '<=', $currentTime) ->where('coupon.usable_end_time', '>=', $currentTime) ->where('coupon.usable_number', '<=', Db::raw('receive.number_remain')) ->where('coupon.market_id', 'in', [0, $marketId]) ->whereIn('coupon.storetype_id', $storetypeIds) ->orderByRaw('coupon.discounts DESC, coupon.full_amount DESC') ->get();
// 分离用户今天用过的优惠券种类
$container = ApplicationContext::getContainer(); $redis = $container->get(Redis::class); $couponIds = $redis->sMembers('coupon_'.date('Ymd').'_used_'.$userId);
foreach ($data as $key => &$item) { if (in_array($item->id, $couponIds)) { $notAvailable[$item->id] = $item; } else { $available[] = $item; } }
return [ 'available' => $available, 'not_available' => array_values($notAvailable) ]; }
/** * @inheritDoc */ public function getOrderCanUseCoupons($orderAmount, $marketId, $userId, $fields=[], $type = 1, $storeTypeIds = [0]) {
// 用户今日使用过的优惠券
$redis = ApplicationContext::getContainer()->get(Redis::class); $couponTodayUsedIds = $redis->sMembers('coupon_'.date('Ymd').'_used_'.$userId); $currentTime = time();
$builder = Db::table('ims_system_coupon_user_receive as receive') ->join('ims_system_coupon_user as coupon', 'coupon.id', '=', 'receive.system_coupon_user_id', 'inner');
if (is_array($fields)&&!empty($fields)) { $builder->select($fields); }
if (is_array($couponTodayUsedIds)&&!empty($couponTodayUsedIds)) { $builder->whereNotIn('coupon.id', $couponTodayUsedIds); }
return $builder->where(['receive.user_id' => $userId]) ->whereIn('receive.status', [0,1]) ->where('receive.number_remain', '>', 0) ->whereIn('coupon.type', [1,$type]) ->where('coupon.full_amount', '<=', $orderAmount) ->where('coupon.usable_start_time', '<=', $currentTime) ->where('coupon.usable_end_time', '>=', $currentTime) ->where('coupon.usable_number', '<=', Db::raw('receive.number_remain')) ->where('coupon.market_id', 'in', [0, $marketId]) ->whereIn('coupon.storetype_id', $storeTypeIds) ->orderByRaw('coupon.discounts DESC, coupon.full_amount DESC') ->get() ->toArray(); }
/** * 缓存优惠券今日使用情况 * @param $userId * @param $couponId * @param $couponRecId * @return bool */ function cacheTodayCouponUsed($userId, $couponId, $couponRecId) {
$redis = ApplicationContext::getContainer()->get(Redis::class);
$setRes = $redis->sAdd( 'coupon_'.date('Ymd').'_used_'.$userId, $couponId );
$expireRes = $redis->expire( 'coupon_'.date('Ymd').'_used_'.$userId, strtotime(date('Y-m-d').' 23:59:59')-time() );
return $setRes&&$expireRes; }
/** * 取消订单返券 * @param $order_id * @return bool */ public function refundOrderCoupons($order_id){ $coupon = CouponUserUse::where([ ['order_main_id','=',$order_id], ['status','=',CouponUserUse::COUPON_USE_STATE_USED], ]) ->select('id','user_receive_id','number') ->first();
if (empty($coupon)) { return ''; }
// 返回用户优惠券数量并更新状态
$res = Db::update("UPDATE ims_system_coupon_user_receive SET number_remain=number_remain+{$coupon->number}, status=IF(number=number_remain,0,1), update_time=".time()."" ." WHERE id={$coupon->user_receive_id} AND number>=(number_remain+{$coupon->number})");
// 更新使用记录状态为已退回
CouponUserUse::where([ ['id','=',$coupon->id], ['status','=',CouponUserUse::COUPON_USE_STATE_USED], ]) ->update([ 'status' => CouponUserUse::COUPON_USE_STATE_CANCEL, 'return_time' => time(), 'update_time' => time(), ]);
//删除当日 redis 使用记录缓存
$order_main = OrderMain::where('id',$order_id) ->select('global_order_id','user_id') ->first(); $redis = ApplicationContext::getContainer()->get(Redis::class); $remRes = $redis->sRem( 'coupon_'.date('Ymd').'_used_'.$order_main->user_id, $coupon->system_coupon_id ); return $res; }
/* 删除-优惠券今日使用的缓存 * @param $userId * @param $couponId * @return bool */ public function clearTodayCouponUsed($userId, $couponId) {
$redis = ApplicationContext::getContainer()->get(Redis::class);
$res = $redis->sRem( 'coupon_'.date('Ymd').'_used_'.$userId, $couponId ); return $res; }
/** * 退款返还优惠券 * 先查询是否正常使用优惠券 * 修改状态,退还领取记录库存,删除ssdb缓存 */ public function orderRefundCoupons($global_order_id) { $time = time(); Db::beginTransaction(); try { $couponUses = CouponUserUse::query() ->select('id','system_coupon_id','user_id','number','user_receive_id') ->where('global_order_id',$global_order_id) ->where('status',CouponUserUse::COUPON_USE_STATE_USED) ->select(); if(!empty($couponUse)){ foreach($couponUses as $use){ $use->status = CouponUserUse::COUPON_USE_STATE_USED; $use->return_time = $time; $use->update_time = $time; $res = $use->save();
$couponReceive = CouponRec::query() ->where('id',$use->user_receive_id) ->whereRaw('number >= number_remain+'.$use->number) ->update([ 'number_remain' => Db::raw('number_remain+'.$use->number), 'status' => Db::raw('IF(number=number_remain,' . CouponRec::STATE_UNUSED . ',' . CouponRec::STATE_SOME . ')'), 'update_time' => $time ]);
$clearUseRedis = $this->clearTodayCouponUsed($use->user_id,$use->system_coupon_id); } }
Db::commit(); return true; } catch (Exception $e) {
$this->log->event(LogLabel::ORDER_LOG, ['msg'=> '订单退款','exception' => $e->getMessage()]); Db::rollBack(); return false; } return true; }}
|