199 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			199 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			PHP
		
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace app\traits\account;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								use app\exception\ApiRedirectException;
							 | 
						||
| 
								 | 
							
								use app\exception\RepositoryException;
							 | 
						||
| 
								 | 
							
								use app\model\Account;
							 | 
						||
| 
								 | 
							
								use app\model\AccountCoupon;
							 | 
						||
| 
								 | 
							
								use app\model\AccountRecord;
							 | 
						||
| 
								 | 
							
								use app\model\Coupon;
							 | 
						||
| 
								 | 
							
								use app\model\Express;
							 | 
						||
| 
								 | 
							
								use app\repository\AccountRepository;
							 | 
						||
| 
								 | 
							
								use think\Collection;
							 | 
						||
| 
								 | 
							
								use think\db\exception\DataNotFoundException;
							 | 
						||
| 
								 | 
							
								use think\db\exception\DbException;
							 | 
						||
| 
								 | 
							
								use think\db\exception\ModelNotFoundException;
							 | 
						||
| 
								 | 
							
								use think\Model;
							 | 
						||
| 
								 | 
							
								use think\Paginator;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * 优惠券相关
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Trait CouponTrait
							 | 
						||
| 
								 | 
							
								 * @package app\traits\order
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								trait CouponTrait
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 领取优惠券
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param int $accountId
							 | 
						||
| 
								 | 
							
								     * @param int $couponId
							 | 
						||
| 
								 | 
							
								     * @return void
							 | 
						||
| 
								 | 
							
								     * @throws DataNotFoundException
							 | 
						||
| 
								 | 
							
								     * @throws DbException
							 | 
						||
| 
								 | 
							
								     * @throws ModelNotFoundException
							 | 
						||
| 
								 | 
							
								     * @throws RepositoryException
							 | 
						||
| 
								 | 
							
								     * @throws ApiRedirectException
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getCoupon(int $accountId, int $couponId)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!$coupon = Coupon::where('id', $couponId)->lock(true)->find()) {
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('优惠券不存在或已下架');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!empty($coupon['deleted_at'])) {
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('优惠券不存在或已下架');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!$account = Account::findById($accountId)) {
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('请先登录');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($coupon['remain'] <= 0) {
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('优惠券已领完');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($coupon['end_at'] <= date('Y-m-d H:i:s')) {
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('优惠券已过期');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (AccountCoupon::where('coupon_id', $couponId)->where('account_id', $accountId)->count() > 0) {
							 | 
						||
| 
								 | 
							
								            throw new RepositoryException('您已领过此券');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($account['phone_active'] != Account::COMMON_ON) {
							 | 
						||
| 
								 | 
							
								            throw new ApiRedirectException('请先完善账号资料');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        AccountCoupon::create([
							 | 
						||
| 
								 | 
							
								            'account_id' => $accountId,
							 | 
						||
| 
								 | 
							
								            'coupon_id' => $couponId,
							 | 
						||
| 
								 | 
							
								            'status' => AccountCoupon::STATUS_NORMAL,
							 | 
						||
| 
								 | 
							
								            'is_taste' => (int)($coupon['type'] == Coupon::TYPE_TASTE),
							 | 
						||
| 
								 | 
							
								            'created_at' => date('Y-m-d H:i:s'),
							 | 
						||
| 
								 | 
							
								        ]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $coupon->inc('receive')->dec('remain')->update();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 用户优惠券详情
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param int $accountId
							 | 
						||
| 
								 | 
							
								     * @param int $couponId
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function userCouponInfo(int $accountId, int $couponId)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return AccountCoupon::findOne(['account_id' => $accountId, 'coupon_id' => $couponId], [], function ($q) {
							 | 
						||
| 
								 | 
							
								            return $q->with(["coupon"]);
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 获取个人优惠券
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param int $accountId
							 | 
						||
| 
								 | 
							
								     * @param string $status 默认normal=未使用
							 | 
						||
| 
								 | 
							
								     * @param int $page
							 | 
						||
| 
								 | 
							
								     * @param int $size 0 不限 获取全部
							 | 
						||
| 
								 | 
							
								     * @return AccountCoupon[]|array|Collection
							 | 
						||
| 
								 | 
							
								     * @throws DataNotFoundException
							 | 
						||
| 
								 | 
							
								     * @throws DbException
							 | 
						||
| 
								 | 
							
								     * @throws ModelNotFoundException
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function couponList(string $status = AccountCoupon::STATUS_NORMAL, int $accountId = 0, int $page = 1, int $size = 0)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $normalList = AccountCoupon::with(['coupon'])->where('account_id', $accountId)
							 | 
						||
| 
								 | 
							
								            ->where('status', AccountCoupon::STATUS_NORMAL)
							 | 
						||
| 
								 | 
							
								            ->select();
							 | 
						||
| 
								 | 
							
								        $expiredList = $normalList->where('end_at', '<', date('Y-m-d H:i:s'))->column('id');
							 | 
						||
| 
								 | 
							
								        if (!empty($expiredList)) {
							 | 
						||
| 
								 | 
							
								            AccountCoupon::whereIn('id', $expiredList)->update(['status' => AccountCoupon::STATUS_INVALID]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (in_array($status, AccountCoupon::statusList())) {
							 | 
						||
| 
								 | 
							
								            // 待查询的优惠券ID列表
							 | 
						||
| 
								 | 
							
								            $withIds = AccountCoupon::where('account_id', $accountId)
							 | 
						||
| 
								 | 
							
								                ->when(!empty($status), function ($q) use ($status) {
							 | 
						||
| 
								 | 
							
								                    $q->where('status', $status);
							 | 
						||
| 
								 | 
							
								                })
							 | 
						||
| 
								 | 
							
								                ->when($size > 0, function ($q) use ($page, $size) {
							 | 
						||
| 
								 | 
							
								                    $q->page($page, $size);
							 | 
						||
| 
								 | 
							
								                })
							 | 
						||
| 
								 | 
							
								                ->order('created_at', 'desc')
							 | 
						||
| 
								 | 
							
								                ->column('coupon_id');
							 | 
						||
| 
								 | 
							
								            return Coupon::whereIn('id', $withIds)
							 | 
						||
| 
								 | 
							
								                ->field('id,name,cover,type,condition,amount,begin_at,end_at')
							 | 
						||
| 
								 | 
							
								                ->select();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($status == 'waiting') {
							 | 
						||
| 
								 | 
							
								            //待领取 可领券的优惠券
							 | 
						||
| 
								 | 
							
								            //排除所有领过优惠券
							 | 
						||
| 
								 | 
							
								            $now = date('Y-m-d H:i:s');
							 | 
						||
| 
								 | 
							
								            $hasIds = AccountCoupon::where('account_id', $accountId)->column('coupon_id');
							 | 
						||
| 
								 | 
							
								            return Coupon::whereNotIn('id', $hasIds)
							 | 
						||
| 
								 | 
							
								                ->whereNull('deleted_at')
							 | 
						||
| 
								 | 
							
								                ->where('begin_at', '<', $now)
							 | 
						||
| 
								 | 
							
								                ->where('end_at', '>', $now)
							 | 
						||
| 
								 | 
							
								                ->where('remain', '>', 0)
							 | 
						||
| 
								 | 
							
								                ->order('sort', 'desc')
							 | 
						||
| 
								 | 
							
								                ->order('created_at', 'desc')
							 | 
						||
| 
								 | 
							
								                ->field('id,name,cover,type,condition,amount,begin_at,end_at')
							 | 
						||
| 
								 | 
							
								                ->select();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return new Collection();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 检测并处理过期优惠券
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param int $accountId
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function checkExpire(int $accountId)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $accountCouponList = AccountCoupon::where('account_id', $accountId)
							 | 
						||
| 
								 | 
							
								            ->where('status', AccountCoupon::STATUS_NORMAL)
							 | 
						||
| 
								 | 
							
								            ->column('coupon_id');
							 | 
						||
| 
								 | 
							
								        $expiredList = Coupon::whereIn('id', $accountCouponList)
							 | 
						||
| 
								 | 
							
								            ->where('end_at', '<=', date('Y-m-d H:i:s'))
							 | 
						||
| 
								 | 
							
								            ->column('id');
							 | 
						||
| 
								 | 
							
								        if (!empty($expiredList)) {
							 | 
						||
| 
								 | 
							
								            AccountCoupon::where('account_id', $accountId)
							 | 
						||
| 
								 | 
							
								                ->whereIn('coupon_id', $expiredList)
							 | 
						||
| 
								 | 
							
								                ->save([
							 | 
						||
| 
								 | 
							
								                    'status' => AccountCoupon::STATUS_INVALID,
							 | 
						||
| 
								 | 
							
								                ]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 创建一个体验券展示二维码
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param int $accountId
							 | 
						||
| 
								 | 
							
								     * @param int $couponId
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function createExperienceCouponQR($accountId, $couponId)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return md5($accountId . AccountCoupon::CODE_SALT . $couponId);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 验证一个体验券展示二维码
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param int $accountId
							 | 
						||
| 
								 | 
							
								     * @param int $couponId
							 | 
						||
| 
								 | 
							
								     * @param string $secret
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function checkExperienceCouponQR($accountId, $couponId, $secret)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return ($secret == md5($accountId . AccountCoupon::CODE_SALT . $couponId)) ? true : "秘钥核验失败";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 |