From d400f971994b5571a5a8b4508f0b36409403ea34 Mon Sep 17 00:00:00 2001 From: Lemon <15040771@qq.com> Date: Mon, 19 Oct 2020 09:34:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=88=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Constants/v3/ErrorCode.php | 6 + app/Controller/v3/CouponController.php | 31 ++++ app/Request/v3/CommunityBindRequest.php | 2 +- app/Request/v3/CouponReceiveRequest.php | 36 ++++ .../v3/Implementations/CouponRecService.php | 171 ++++++++++++++++++ .../Interfaces/CouponRecServiceInterface.php | 2 + config/routes.php | 2 + 7 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 app/Request/v3/CouponReceiveRequest.php diff --git a/app/Constants/v3/ErrorCode.php b/app/Constants/v3/ErrorCode.php index 716e2cc..97f6337 100644 --- a/app/Constants/v3/ErrorCode.php +++ b/app/Constants/v3/ErrorCode.php @@ -324,6 +324,12 @@ class ErrorCode extends AbstractConstants */ const COUPON_USE_FAILURE = 1202; + /** + * 不是新用户无法领券 + * @Message("不是新用户无法领券") + */ + const COUPON_IS_NOT_NEW_USER = 1203; + /************************************/ /* 提现相关 1251-1300 */ /************************************/ diff --git a/app/Controller/v3/CouponController.php b/app/Controller/v3/CouponController.php index 2048fbe..ab98ed8 100644 --- a/app/Controller/v3/CouponController.php +++ b/app/Controller/v3/CouponController.php @@ -12,10 +12,15 @@ declare(strict_types=1); namespace App\Controller\v3; +use App\Constants\v3\ErrorCode; +use App\Exception\ErrorCodeException; +use App\Constants\v3\OrderState; +use App\Model\v3\OrderMain; use App\Request\v3\UserRequest; use Hyperf\Di\Annotation\Inject; use App\Controller\BaseController; use App\Service\v3\Interfaces\CouponRecServiceInterface; +use App\Request\v3\CouponReceiveRequest; class CouponController extends BaseController { @@ -75,4 +80,30 @@ class CouponController extends BaseController return $this->success($res); } + public function getAvailableListByNewUser() + { + $userId = $this->request->input("user_id", 0); + $receiveType = $this->request->input("receive_type", 0); + $newUserCheck = OrderMain::query() + ->where('user_id',$userId) + ->whereIn('state',OrderState::CAN_DEL) + ->whereIn('state',OrderState::REFUND) + ->exists(); + if($newUserCheck){ + throw new ErrorCodeException(ErrorCode::COUPON_IS_NOT_NEW_USER,'',$userId); + } + $res = $this->couponRecService->getAvailableList($userId,$receiveType); + return $this->success($res); + } + + /** + * 用户领取优惠卷 + */ + public function Receive(CouponReceiveRequest $request) + { + $userId = $this->request->input("user_id", 0); + $receiveType = $this->request->input("receive_type", 0); + $ids = $this->request->input("ids", ''); + $res['statistics'] = $this->couponRecService->receive($userId,$receiveType,$ids); + } } diff --git a/app/Request/v3/CommunityBindRequest.php b/app/Request/v3/CommunityBindRequest.php index 3f10776..101ab65 100644 --- a/app/Request/v3/CommunityBindRequest.php +++ b/app/Request/v3/CommunityBindRequest.php @@ -23,7 +23,7 @@ class CommunityBindRequest extends BaseFormRequest { return [ 'source_id' => 'required|nonempty', - 'user_id' => 'required|nonempty|exists_enable:ims_cjdc_user,id', + 'user_id' => 'required|nonempty|exists_enable:lanzu_user,id', 'json_data' => 'json', ]; } diff --git a/app/Request/v3/CouponReceiveRequest.php b/app/Request/v3/CouponReceiveRequest.php new file mode 100644 index 0000000..853601a --- /dev/null +++ b/app/Request/v3/CouponReceiveRequest.php @@ -0,0 +1,36 @@ + 'required|nonempty|integer', + 'receive_type' => 'required|nonempty|integer', + 'ids' => 'required', + ]; + } + + /** + * @return array + */ + public function messages(): array + { + return [ + '*.*' => ':attribute无效', + ]; + } + + public function attributes(): array + { + return parent::attributes(); + } +} \ No newline at end of file diff --git a/app/Service/v3/Implementations/CouponRecService.php b/app/Service/v3/Implementations/CouponRecService.php index 9919078..3ea449f 100644 --- a/app/Service/v3/Implementations/CouponRecService.php +++ b/app/Service/v3/Implementations/CouponRecService.php @@ -4,7 +4,9 @@ namespace App\Service\v3\Implementations; use App\Model\v3\Coupon; use App\Model\v3\CouponRec; +use App\Model\v3\CouponRecType; use App\Model\v3\GoodsActivity; +use App\Service\CommonService; use App\Service\v3\Interfaces\CouponRecServiceInterface; use App\Service\v3\Interfaces\CouponServiceInterface; use App\Service\v3\Interfaces\ShopCartServiceInterface; @@ -12,6 +14,8 @@ use Hyperf\DbConnection\Db; use Hyperf\Redis\Redis; use Hyperf\Utils\ApplicationContext; use Hyperf\Di\Annotation\Inject; +use App\Constants\v3\SsdbKeys; +use App\TaskWorker\SSDBTask; class CouponRecService implements CouponRecServiceInterface { @@ -28,6 +32,12 @@ class CouponRecService implements CouponRecServiceInterface */ protected $couponService; + /** + * @Inject + * @var HelperService + */ + protected $helperService; + public function do() { // TODO: Implement do() method. @@ -290,4 +300,165 @@ class CouponRecService implements CouponRecServiceInterface } return $res; } + + public function getAvailableList($userId,$receiveType) + { + /* 优惠券活动标志 2 */ + $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); + $couponActivity = $ssdb->exec('hgetall', SsdbKeys::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 = []; + // 渠道开启,查询该渠道可以领取的优惠券ID + // 渠道未开启,查询所有优惠券 + if (env('SUB_CHANNEL') == 1) { + $c_ids = CouponRecType::join('lanzu_coupon','lanzu_coupon.id','lanzu_coupon_receive_type.coupon_id') + ->where([ + ['lanzu_coupon_receive_type.receive_type','=',$receiveType], + ['lanzu_coupon.end_time','>',$nowTime], + ['lanzu_coupon.start_time','<=',$nowTime], + ['lanzu_coupon.status','=',1] + ]) + ->pluck('lanzu_coupon.id'); + } else { + $c_ids = Coupon::where([ + ['end_time','>',$nowTime], + ['start_time','<=',$nowTime], + ['status','=',1] + ])->pluck('id'); + } + + $couponReceive = CouponRec::where('user_id',$userId); + + // 渠道开启,查询该用户在此渠道领过的优惠券ID + if (env('SUB_CHANNEL') == 1) { + $couponReceive->where('receive_type', $receiveType); + } + $cr_ids = $couponReceive->pluck('coupon_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->helperService->nonempty($couponActivity['forward']) )? [] : explode(',',$couponActivity['forward']); + // 所有优惠券 + $couponIds = array_merge($couponIds,$couponReceiveIds); + + $whereC = [ + ['lanzu_coupon.end_time','>',$nowTime], + ['lanzu_coupon.start_time','<=',$nowTime], + ['lanzu_coupon.status','=',1] + ]; + // 查询领取型1 和 转发型2 + $whereActiveType = [1,2]; + + if (env('SUB_CHANNEL') == 1) { + array_push($whereC, ['type.receive_type','=', $receiveType]); + } + + $coupons = Coupon::join('lanzu_coupon_receive_type as type', 'lanzu_coupon.id', '=', 'type.coupon_id') + ->whereIn('lanzu_coupon.id', $couponIds) + ->whereIn('lanzu_coupon.active_type', $whereActiveType) + ->where($whereC) + ->whereRaw('lanzu_coupon.inventory_use < lanzu_coupon.inventory and lanzu_coupon.inventory-lanzu_coupon.inventory_use >= type.one_receive_number') + ->select('lanzu_coupon.*','type.one_receive_number') + ->orderBy('lanzu_coupon.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; + } + + /** + * @param $userId + * @param $receiveType + * @param $ids + */ + public function receive($userId, $receiveType, $ids) + { + $ids = explode(',', $ids); + $now = time(); + + $success = []; + $fail = []; + + // if ($this->empty($userId) || $this->empty($receiveType) || $this->empty($ids)) { + // return [ + // 'success' => $success, + // 'fail' => $fail, + // ]; + // } + + Db::transaction(function () use ($ids,$receiveType,$userId,&$success,&$fail,$now) { + //读写锁,完全控制,性能底 + $cps = Coupon::whereIn('id', $ids)->lockForUpdate()->get(); + //写锁,可能在高并发下,读取到脏数据,写入可能有超发情况 + //$cps = Coupon::whereIn('id', $ids)->sharedLock()->get(); + + foreach ($cps as $key => $cp) { + + $where = [ + 'coupon_id' => $cp->id, + ]; + + if (env('SUB_CHANNEL') == 1) { + $where['receive_type'] = $receiveType; + } + + $oneReceiveNumber = CouponRecType::where($where)->value('one_receive_number'); + + $cr = new CouponRec; + $cr->user_id = $userId; + $cr->coupon_id = $cp->id; + $cr->order_main_id = 0; + $cr->receive_time = $now; + $cr->number = $oneReceiveNumber; + $cr->number_remain = $oneReceiveNumber; + $cr->status = 0; + $cr->receive_type = $receiveType; + //如果优惠卷库存小于等于已领取的数量, 则返回领取失败的优惠券 + if ($cp->inventory<=$cp->inventory_use||$cp->inventory<($cp->inventory_use+$cr->number)){ + $fail[] = $cp; + }else{ + $cp->inventory_use += $cr->number;//记录已领取的数量 + if ($cr->save()&&$cp->save()) { + $success[] = $cp; + } else { + $fail[] = $cp; + } + } + } + }); + } } \ No newline at end of file diff --git a/app/Service/v3/Interfaces/CouponRecServiceInterface.php b/app/Service/v3/Interfaces/CouponRecServiceInterface.php index 83c5131..aacfc1a 100644 --- a/app/Service/v3/Interfaces/CouponRecServiceInterface.php +++ b/app/Service/v3/Interfaces/CouponRecServiceInterface.php @@ -16,4 +16,6 @@ interface CouponRecServiceInterface * @return mixed */ public function statistics($userId); + public function getAvailableList($userId,$receiveType); + public function receive($userId,$receiveType,$ids); } \ No newline at end of file diff --git a/config/routes.php b/config/routes.php index 53455dc..3a80997 100644 --- a/config/routes.php +++ b/config/routes.php @@ -165,6 +165,8 @@ Router::addGroup('/v3/', function () { Router::post('goods/create', 'App\Controller\v3\GoodsController@create'); Router::post('goods/updateOnSale', 'App\Controller\v3\GoodsController@updateOnSale'); Router::post('store/updateIsRest', 'App\Controller\v3\StoreController@updateIsRest'); + Router::post('coupon/getAvailableListByNewUser', 'App\Controller\v3\CouponController@getAvailableListByNewUser'); + Router::post('coupon/receive', 'App\Controller\v3\CouponController@receive'); },['middleware' => [\App\Middleware\Auth\ApiMiddleware::class, \App\Middleware\Auth\UserMiddleware::class]]); // 微信支付回调