building-sign/app/traits/account/CouponTrait.php

202 lines
5.8 KiB
PHP
Raw Permalink Normal View History

2023-01-09 08:41:41 +00:00
<?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"]);
});
}
/**
* 过期优惠券检测并处理
*
* @return bool
*/
public function expireHandle(): bool
{
$expiredCouponList = Coupon::where('end_at', '<', date('Y-m-d H:i:s'))->column('id');
if ($expiredCouponList) {
AccountCoupon::whereIn('coupon_id', $expiredCouponList)
->where('status', self::STATUS_NORMAL)
->update(['status' => AccountCoupon::STATUS_INVALID]);
}
return true;
}
/**
* 获取个人优惠券
*
* @param array $where
* @param int $page
* @param int $size 0 不限 获取全部
* @return AccountCoupon[]|array
*/
public function couponList(array $where, int $page = 1, int $size = 10): array
{
$this->expireHandle();
$status = $where['status'] ?? AccountCoupon::STATUS_NORMAL;
$accountId = $where['account_id'] ?? 0;
$condition = $where['condition'] ?? 0;
$page = $page ?: 1;
$size = $size ?: 10;
$res = [
'total' => 0,
'current' => $page,
'size' => $size,
'list' => new Collection(),
];
$query = AccountCoupon::alias('ac')
->leftJoin('coupon c', 'ac.coupon_id = c.id')
->where('ac.account_id', $accountId)
->where('ac.status', $status)
->where('c.condition', '<=', $condition);
$res['total'] = $query->count();
if ($res['total'] > 0) {
$list = $query->field('ac.id,ac.account_id,ac.created_at,ac.coupon_id,ac.status,c.amount,c.name,c.condition,c.begin_at,c.end_at')
->page($page, $size)
->order('created_at', 'desc')
->select();
$res['list'] = $list;
}
return $res;
}
/**
* 检测并处理过期优惠券
*
* @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 : "秘钥核验失败";
}
}