You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
7.9 KiB
237 lines
7.9 KiB
<?php
|
|
|
|
namespace App\Service\v3\Implementations;
|
|
|
|
use App\Commons\Log;
|
|
use App\Constants\v3\ActivityType;
|
|
use App\Constants\v3\ErrorCode;
|
|
use App\Constants\v3\Goods as GoodsConstants;
|
|
use App\Constants\v3\LogLabel;
|
|
use App\Constants\v3\SsdbKeys;
|
|
use App\Model\v3\Store;
|
|
use App\Service\v3\Interfaces\GoodsActivityServiceInterface;
|
|
use App\Service\v3\Interfaces\GoodsInventoryServiceInterface;
|
|
use App\TaskWorker\SSDBTask;
|
|
use App\Model\v3\GoodsActivity;
|
|
use App\Model\v3\GoodsActivityBanner;
|
|
use Hyperf\Redis\Redis;
|
|
use Hyperf\Utils\ApplicationContext;
|
|
use Hyperf\Di\Annotation\Inject;
|
|
|
|
class GoodsActivityService implements GoodsActivityServiceInterface
|
|
{
|
|
|
|
/**
|
|
* @Inject
|
|
* @var Log
|
|
*/
|
|
protected $log;
|
|
|
|
/**
|
|
* @Inject
|
|
* @var GoodsInventoryServiceInterface
|
|
*/
|
|
protected $goodsInventoryService;
|
|
|
|
public function do($goodsId)
|
|
{
|
|
|
|
}
|
|
|
|
public function check(GoodsActivity $goods, $num, $userId)
|
|
{
|
|
|
|
if (empty($goods)) {
|
|
return ErrorCode::GOODS_ACTIVITY_NOT_EXISTS;
|
|
}
|
|
|
|
// 活动是否已经结束
|
|
if ($goods->expire_time < time()) {
|
|
return ErrorCode::GOODS_ACTIVITY_EXPIRED;
|
|
}
|
|
|
|
// 商户歇业
|
|
if(is_null($goods->store) || $goods->store->is_open == 0 || $goods->store->is_rest == 1){
|
|
return ErrorCode::STORE_REST;
|
|
}
|
|
|
|
// 商品下架或已删除
|
|
if($goods->on_sale == 0 || !is_null($goods->deleted_at)){
|
|
return ErrorCode::GOODS_ACTIVITY_ON_SALE_NO;
|
|
}
|
|
|
|
// 商品库存不足
|
|
// 获取冻结的库存
|
|
$inventoryFrozen = $this->goodsInventoryService->getSold(2, $goods->id);
|
|
// $inventoryFrozen = 0;
|
|
if($goods->is_infinite != 1 && $goods->inventory < ($num+$inventoryFrozen)){
|
|
return ErrorCode::GOODS_ACTIVITY_INVENTORY_ERROR;
|
|
}
|
|
|
|
// 是否超过限购数量
|
|
if (($goods->restrict_num <= $inventoryFrozen || $goods->restrict_num <= 0) && $goods->restrict_num < $num) {
|
|
return ErrorCode::GOODS_ACTIVITY_RESTRICT_LIMIT;
|
|
}
|
|
|
|
// 是否已经购买过(某个时间段内,时间段有商品的限制)
|
|
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
|
|
$hasBuy = $ssdb->exec('get', SsdbKeys::ACTIVITY_GOODS_BUY_RECORD.$userId.'_'.$goods->type.'_'.$goods->id);
|
|
if ($hasBuy && $hasBuy >= $goods->time_limit_num) {
|
|
return ErrorCode::GOODS_ACTIVITY_BUY;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function undo()
|
|
{
|
|
// TODO: Implement undo() method.
|
|
}
|
|
|
|
public function getBanner($goodsId)
|
|
{
|
|
$banner = GoodsActivityBanner::query()->where('goods_id',$goodsId)->orderByDesc('type')->get();
|
|
return $banner;
|
|
}
|
|
|
|
public function detail($goodsId)
|
|
{
|
|
$res = GoodsActivity::query()->with('store')->where('id',$goodsId)->first();
|
|
return $res;
|
|
}
|
|
|
|
public function cacheRecord($goodsId, $num, $userId)
|
|
{
|
|
|
|
$goods = GoodsActivity::query()
|
|
->where('id', $goodsId)
|
|
->first();
|
|
|
|
$ssdbKey = SsdbKeys::ACTIVITY_GOODS_BUY_RECORD.$userId.'_'.$goods->type.'_'.$goodsId;
|
|
|
|
$expireTime = 0;
|
|
if ($goods->time_limit_days >= 1) {
|
|
$expireTime += strtotime(date('Y-m-d 23:59:59')) - time();
|
|
$expireTime += ($goods->time_limit_days-1) * 86400;
|
|
} elseif ($goods->time_limit_days > 0 && $goods->time_limit_days < 1) {
|
|
$expireTime += bcmul($goods->time_limit_days,86400,0);
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
|
|
|
|
if (!$ssdb->exec('exists', $ssdbKey)) {
|
|
$ssdb->exec('set', $ssdbKey, $num);
|
|
$ssdb->exec('expire', $ssdbKey, $expireTime);
|
|
} else {
|
|
$ssdb->exec('incr', $ssdbKey, $num);
|
|
}
|
|
|
|
}
|
|
|
|
public function clearCacheRecord($goodsId, $num, $userId)
|
|
{
|
|
$goods = GoodsActivity::query()
|
|
->where('id', $goodsId)
|
|
->first();
|
|
if (empty($goods)) {
|
|
return true;
|
|
}
|
|
$ssdbKey = SsdbKeys::ACTIVITY_GOODS_BUY_RECORD.$userId.'_'.$goods->type.'_'.$goodsId;
|
|
|
|
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
|
|
|
|
if ($ssdb->exec('exists', $ssdbKey)) {
|
|
$res = $ssdb->exec('incr', $ssdbKey, -1*$num);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 统计订单中活动商品的数量,并校验
|
|
* @param $goodsIds
|
|
* @param int $limitNum
|
|
* @return bool
|
|
*/
|
|
public function checkOrderActivityCount($goodsIds, $limitNum=1)
|
|
{
|
|
|
|
$sourceGoods = GoodsActivity::query()
|
|
->whereIn('id', $goodsIds)
|
|
->get()->toArray();
|
|
|
|
$redis = ApplicationContext::getContainer()->get(Redis::class);
|
|
$activityTypeLimitNumsKey = 'activity_type_limit_nums';
|
|
$limitNums = $redis->hGetAll($activityTypeLimitNumsKey);
|
|
|
|
if (empty($limitNums)) {
|
|
|
|
$limitNums = [
|
|
ActivityType::FLASH_SALE => 0,
|
|
ActivityType::GROUP_BUY => 0,
|
|
ActivityType::NEW_PRODUCT => 0,
|
|
];
|
|
}
|
|
|
|
$buyNum = [
|
|
ActivityType::FLASH_SALE => 0,
|
|
ActivityType::GROUP_BUY => 0,
|
|
ActivityType::NEW_PRODUCT => 0,
|
|
];
|
|
|
|
foreach ($sourceGoods as $key => &$goods) {
|
|
|
|
if ($limitNums[$goods['type']] == 0) { // 不限制同类购买商品种数,也就是可以同时购买多款不同商品
|
|
continue;
|
|
}
|
|
|
|
$buyNum[$goods['type']] += 1;
|
|
if ($buyNum[$goods['type']] > $limitNums[$goods['type']]) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getList($marketId,$page,$pagesize)
|
|
{
|
|
$storeTable = ApplicationContext::getContainer()->get(Store::class)->getTable();
|
|
$goodsTable = ApplicationContext::getContainer()->get(GoodsActivity::class)->getTable();
|
|
|
|
$builder = GoodsActivity::query()
|
|
->join($storeTable, ''.$storeTable.'.id', '=', ''.$goodsTable.'.store_id')
|
|
->with(['store'])
|
|
//->where([''.$goodsTable.'.type' => $type])
|
|
->where(function ($query) use ($marketId, $goodsTable) {
|
|
$query->whereJsonContains(''.$goodsTable.'.market_ids', [(string)$marketId])
|
|
->orWhereJsonLength(''.$goodsTable.'.market_ids', '=', 0);
|
|
})
|
|
->where([''.$goodsTable.'.on_sale' => GoodsConstants::ON_SALE_YES])
|
|
// ->where(function ($query) use ($goodsTable) {
|
|
// $query->where(''.$goodsTable.'.inventory', '>', 0)->orWhere(''.$goodsTable.'.is_infinite', '=', 1);
|
|
// })
|
|
->whereRaw(''.$goodsTable.'.deleted_at IS NULL')
|
|
->where([''.$storeTable.'.market_id' => $marketId])
|
|
->where([''.$storeTable.'.is_open' => \App\Constants\v3\Store::IS_OPEN_YES])
|
|
->where([''.$storeTable.'.is_rest' => \App\Constants\v3\Store::IS_REST_NO])
|
|
->where('time1', '<=', date('H:i'))
|
|
->where(function ($query) {
|
|
$query->where('time2', '>=', date('H:i'))
|
|
->orWhere('time4', '>=', date('H:i'));
|
|
})
|
|
->where(''.$goodsTable.'.expire_time', '>', time());
|
|
$paginate = $builder->select(''.$goodsTable.'.*')->addSelect(''.$goodsTable.'.sales as total_sales')
|
|
->orderBy(''.$goodsTable.'.sort', 'DESC')
|
|
->orderBy(''.$goodsTable.'.expire_time', 'ASC')
|
|
->orderBy(''.$goodsTable.'.created_at', 'DESC')
|
|
->paginate($pagesize);
|
|
$goodsArr = $paginate->toArray();
|
|
$goods = collect($goodsArr['data']);
|
|
$goods = $goods->sortBy(function ($product, $key) {
|
|
return $product['noneffective_note'];
|
|
});
|
|
$goods = $goods->values()->all();
|
|
return ['has_more_pages' => $paginate->hasMorePages(), 'goods' => $goods];
|
|
}
|
|
}
|