caipan_shop_admin/app/traits/spu/LimitTimeTrait.php

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;
}
}
}