266 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			PHP
		
	
	
<?php
 | 
						|
 | 
						|
namespace app\traits\spu;
 | 
						|
 | 
						|
use app\exception\RepositoryException;
 | 
						|
use app\model\mall\SpuLimitTime;
 | 
						|
use app\model\Sku;
 | 
						|
use app\model\Spu;
 | 
						|
use app\model\Spu as SpuModel;
 | 
						|
use app\repository\SpuRepository;
 | 
						|
use Exception;
 | 
						|
use think\facade\Db;
 | 
						|
use think\facade\Log;
 | 
						|
use think\Model;
 | 
						|
 | 
						|
trait LimitTimeTrait
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * 添加限时折扣
 | 
						|
     *
 | 
						|
     * @param  array  $data  基础信息
 | 
						|
     * @param  array  $skus  规格信息
 | 
						|
     * @return Model
 | 
						|
     * @throws RepositoryException
 | 
						|
     */
 | 
						|
    public function addLimitTime(array $data, array $skus): Model
 | 
						|
    {
 | 
						|
        Db::startTrans();
 | 
						|
        try {
 | 
						|
            $now = date('Y-m-d H:i:s');
 | 
						|
 | 
						|
            $spuFields = ['id', 'spu_type_id', 'activity_id', 'is_activity', 'activity_type', 'multi_spec'];
 | 
						|
            if (!$spuInfo = SpuModel::findById($data['spu_id'], $spuFields)) {
 | 
						|
                throw new RepositoryException('商品不存在');
 | 
						|
            }
 | 
						|
 | 
						|
            if ($spuInfo['activity_type'] != SpuModel::TYPE_NORMAL) {
 | 
						|
                throw new RepositoryException('该商品已参与其他活动');
 | 
						|
            }
 | 
						|
 | 
						|
            if ($spuInfo['multi_spec'] == SpuModel::COMMON_OFF) {
 | 
						|
                $skus = [$skus];
 | 
						|
            }
 | 
						|
 | 
						|
            $multiSpec = (bool) $spuInfo['multi_spec'];
 | 
						|
 | 
						|
            $data['created_at'] = $now;
 | 
						|
            $data['updated_at'] = $now;
 | 
						|
            $limitTime          = SpuLimitTime::create($data);
 | 
						|
 | 
						|
            // 创建活动SKU
 | 
						|
            foreach ($skus as &$sku) {
 | 
						|
                unset($sku['id']);
 | 
						|
                unset($sku['coding']);
 | 
						|
                $sku['spu_id'] = $data['spu_id'];
 | 
						|
            }
 | 
						|
            $skuData = $this->handleSku($limitTime['id'], $skus, [], SpuLimitTime::TYPE, $multiSpec);
 | 
						|
 | 
						|
            (new Sku())->saveAll($skuData['data']);
 | 
						|
 | 
						|
            $limitTime->save([
 | 
						|
                'spec' => json_encode($skuData['spec'], JSON_UNESCAPED_UNICODE)
 | 
						|
            ]);
 | 
						|
 | 
						|
            // 修改基础商品
 | 
						|
            $spuInfo->save([
 | 
						|
                'activity_id'   => $limitTime['id'],
 | 
						|
                'activity_type' => SpuLimitTime::TYPE,
 | 
						|
                'is_activity'   => SpuLimitTime::COMMON_ON,
 | 
						|
            ]);
 | 
						|
 | 
						|
            Db::commit();
 | 
						|
            return $limitTime;
 | 
						|
        } catch (RepositoryException $e) {
 | 
						|
            // 回滚事务
 | 
						|
            Db::rollback();
 | 
						|
            throw $e;
 | 
						|
        } catch (Exception $e) {
 | 
						|
            SpuRepository::log($e->getMessage(), $e);
 | 
						|
            // 回滚事务
 | 
						|
            Db::rollback();
 | 
						|
            throw new RepositoryException('限时折扣创建失败');
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 编辑限时折扣
 | 
						|
     *
 | 
						|
     * @param  int  $id  限时折扣ID
 | 
						|
     * @param  array  $data  基础信息
 | 
						|
     * @param  array  $skus  规格信息
 | 
						|
     * @return Model
 | 
						|
     * @throws RepositoryException
 | 
						|
     */
 | 
						|
    public function editLimitTime(int $id, array $data, array $skus): Model
 | 
						|
    {
 | 
						|
        Db::startTrans();
 | 
						|
        try {
 | 
						|
            if (!$limitTime = SpuLimitTime::findById($id)) {
 | 
						|
                throw new RepositoryException('记录不存在');
 | 
						|
            }
 | 
						|
 | 
						|
            $spuFields = ['id', 'spu_type_id', 'activity_id', 'activity_type', 'is_activity', 'multi_spec'];
 | 
						|
            if (!$spuInfo = SpuModel::findById($limitTime['spu_id'], $spuFields)) {
 | 
						|
                throw new RepositoryException('商品不存在');
 | 
						|
            }
 | 
						|
 | 
						|
            if ($spuInfo['activity_type'] != SpuModel::TYPE_NORMAL && $spuInfo['activity_id'] != $id) {
 | 
						|
                throw new RepositoryException('该商品已参与其他活动');
 | 
						|
            }
 | 
						|
 | 
						|
            $multiSpec = (bool) $spuInfo['multi_spec'];
 | 
						|
 | 
						|
            if (!$multiSpec) {
 | 
						|
                $skus = [$skus];
 | 
						|
            }
 | 
						|
 | 
						|
            $data['updated_at'] = date('Y-m-d H:i:s');
 | 
						|
 | 
						|
            $originalSkuList = Sku::where('spu_activity_id', $id)
 | 
						|
                ->where('spu_id', 0)
 | 
						|
                ->where('type', SpuLimitTime::TYPE)
 | 
						|
                ->where('enable', Sku::COMMON_ON)
 | 
						|
                ->order('sort', 'asc')
 | 
						|
                ->order('id', 'asc')
 | 
						|
                ->select()
 | 
						|
                ->toArray();
 | 
						|
 | 
						|
            $skuData = $this->handleSku($id, $skus, array_column($originalSkuList, 'id'), SpuLimitTime::TYPE, $multiSpec);
 | 
						|
 | 
						|
            (new Sku())->saveAll($skuData['data']);
 | 
						|
            (new Sku())->where('id', 'in', $skuData['delete'])->delete();
 | 
						|
 | 
						|
            $data['spec']        = json_encode($skuData['spec'], JSON_UNESCAPED_UNICODE);
 | 
						|
            $data['is_restore']  = SpuLimitTime::COMMON_OFF;
 | 
						|
            $data['restored_at'] = null;
 | 
						|
            $limitTime->save($data);
 | 
						|
 | 
						|
            // 修改基础商品
 | 
						|
            $spuInfo->save([
 | 
						|
                'activity_id'   => $id,
 | 
						|
                'activity_type' => SpuLimitTime::TYPE,
 | 
						|
                'is_activity'   => SpuModel::COMMON_ON,
 | 
						|
            ]);
 | 
						|
 | 
						|
            Db::commit();
 | 
						|
            return $limitTime;
 | 
						|
        } catch (RepositoryException $e) {
 | 
						|
            // 回滚事务
 | 
						|
            Db::rollback();
 | 
						|
            throw $e;
 | 
						|
        } catch (Exception $e) {
 | 
						|
            SpuRepository::log($e->getMessage(), $e);
 | 
						|
            // 回滚事务
 | 
						|
            Db::rollback();
 | 
						|
            throw new RepositoryException('限时折扣编辑失败');
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 还原限时折扣
 | 
						|
     * @param  array  $ids  为空则还原所有过期的活动
 | 
						|
     * @param  bool  $delete  是否删除
 | 
						|
     * @return bool
 | 
						|
     */
 | 
						|
    public function restoreLimitTime(array $ids = [], bool $delete = false): bool
 | 
						|
    {
 | 
						|
        Db::startTrans();
 | 
						|
        try {
 | 
						|
            $where   = [];
 | 
						|
            $where[] = ['is_restore', '=', SpuLimitTime::COMMON_OFF];
 | 
						|
            $now     = date('Y-m-d H:i:s');
 | 
						|
            if (!empty($ids)) {
 | 
						|
                // 还原指定ID的活动
 | 
						|
                $where[] = ['id', 'in', $ids];
 | 
						|
            } else {
 | 
						|
                // 还原所有过期活动
 | 
						|
                $where[] = ['end_at', '<', $now];
 | 
						|
            }
 | 
						|
            $spuIds = SpuLimitTime::where($where)->column('spu_id');
 | 
						|
            if (empty($spuIds)) {
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
 | 
						|
            Spu::whereIn('id', $spuIds)
 | 
						|
                ->where('is_activity', Spu::COMMON_ON)
 | 
						|
                ->where('activity_type', SpuLimitTime::TYPE)
 | 
						|
                ->save([
 | 
						|
                    'is_activity'   => Spu::COMMON_OFF,
 | 
						|
                    'activity_type' => Spu::TYPE_NORMAL,
 | 
						|
                    'activity_id'   => 0,
 | 
						|
                ]);
 | 
						|
 | 
						|
            if ($delete) {
 | 
						|
                SpuLimitTime::whereIn('id', $ids)->whereNull('deleted_at')->save(
 | 
						|
                    [
 | 
						|
                        'is_restore'  => SpuLimitTime::COMMON_ON,
 | 
						|
                        'restored_at' => $now,
 | 
						|
                        'deleted_at'  => $now,
 | 
						|
                    ]
 | 
						|
                );
 | 
						|
                Sku::whereIn('spu_activity_id', $ids)->save(['deleted_at' => $now]);
 | 
						|
            } else {
 | 
						|
                SpuLimitTime::where($where)->save(
 | 
						|
                    ['is_restore' => SpuLimitTime::COMMON_ON, 'restored_at' => $now]
 | 
						|
                );
 | 
						|
            }
 | 
						|
 | 
						|
            Db::commit();
 | 
						|
            return true;
 | 
						|
        } catch (Exception $e) {
 | 
						|
            Db::rollback();
 | 
						|
            Log::error('还原限时折扣失败 msg:'.$e->getMessage());
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 重启活动
 | 
						|
     * @param  int  $id  活动ID
 | 
						|
     * @return bool
 | 
						|
     * @throws RepositoryException
 | 
						|
     */
 | 
						|
    public function restart(int $id): bool
 | 
						|
    {
 | 
						|
        Db::startTrans();
 | 
						|
        try {
 | 
						|
            $where   = [];
 | 
						|
 | 
						|
            $item = SpuLimitTime::findById($id);
 | 
						|
            if (!$item) {
 | 
						|
                throw new RepositoryException('活动不存在');
 | 
						|
            }
 | 
						|
 | 
						|
            // 检测所选商品 是否存在参加其他活动
 | 
						|
            $spu = Spu::findById($item['spu_id'], ['id', 'activity_id', 'is_activity', 'activity_type']);
 | 
						|
            if (!$spu || $spu['deleted_at']) {
 | 
						|
                throw new RepositoryException('商品不存在');
 | 
						|
            }
 | 
						|
 | 
						|
            if ($spu['activity_id'] > 0 && $spu['activity_id'] != $item['spu_id']) {
 | 
						|
                throw new RepositoryException('该商品已参加其他活动');
 | 
						|
            }
 | 
						|
 | 
						|
            $item->save(
 | 
						|
                ['is_restore' => SpuLimitTime::COMMON_OFF, 'restored_at' => null]
 | 
						|
            );
 | 
						|
 | 
						|
            $spu->save([
 | 
						|
                'is_activity' => Spu::COMMON_ON,
 | 
						|
                'activity_type' => Spu::TYPE_LIMIT_TIME,
 | 
						|
                'activity_id' => $id,
 | 
						|
            ]);
 | 
						|
 | 
						|
            Db::commit();
 | 
						|
            return true;
 | 
						|
        } catch (RepositoryException $e) {
 | 
						|
            Db::rollback();
 | 
						|
            throw $e;
 | 
						|
        } catch (Exception $e) {
 | 
						|
            Db::rollback();
 | 
						|
            Log::error('还原限时折扣失败 msg:'.$e->getMessage());
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |