199 lines
6.2 KiB
PHP
Executable File
199 lines
6.2 KiB
PHP
Executable File
<?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 : "秘钥核验失败";
|
|
}
|
|
|
|
|
|
} |