266 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			266 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
| <?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;
 | |
|         }
 | |
|     }
 | |
| } |