146 lines
4.4 KiB
PHP
146 lines
4.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service;
|
|
|
|
use App\Model\SkuMapping;
|
|
use App\Model\SkuOrigin;
|
|
use Hyperf\Stringable\Str;
|
|
|
|
/**
|
|
* SKU 业务逻辑服务
|
|
*
|
|
* 负责 platform_outer_sku 的自动生成、重复检测等业务逻辑
|
|
*/
|
|
class SkuService
|
|
{
|
|
/**
|
|
* 生成 platform_outer_sku
|
|
*
|
|
* @param string $strategy 生成策略:prefix | prefix_random | manual
|
|
* @param string $origin_sku 原始 SKU 编码
|
|
* @param string $prefix 前缀
|
|
* @param int $random_length 随机部分长度(仅 prefix_random 模式)
|
|
* @param string|null $manual_value 手动输入值(仅 manual 模式)
|
|
* @return string 生成的 platform_outer_sku
|
|
*/
|
|
public function generatePlatformOuterSku(
|
|
string $strategy,
|
|
string $origin_sku,
|
|
string $prefix = '',
|
|
int $random_length = 4,
|
|
?string $manual_value = null,
|
|
): string {
|
|
return match ($strategy) {
|
|
'prefix' => $this->generatePrefixSku($prefix, $origin_sku),
|
|
'prefix_random' => $this->generatePrefixRandomSku($prefix, $random_length),
|
|
'manual' => $manual_value ?? '',
|
|
default => throw new \InvalidArgumentException("不支持的生成策略: {$strategy}"),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 前缀模式:{prefix}_{origin_sku}
|
|
*/
|
|
private function generatePrefixSku(string $prefix, string $origin_sku): string
|
|
{
|
|
if ($prefix === '') {
|
|
return $origin_sku;
|
|
}
|
|
return "{$prefix}_{$origin_sku}";
|
|
}
|
|
|
|
/**
|
|
* 前缀+随机模式:{prefix}_{random_string}
|
|
*/
|
|
private function generatePrefixRandomSku(string $prefix, int $random_length): string
|
|
{
|
|
$random_part = Str::upper(Str::random($random_length));
|
|
if ($prefix === '') {
|
|
return $random_part;
|
|
}
|
|
return "{$prefix}_{$random_part}";
|
|
}
|
|
|
|
/**
|
|
* 构建生成策略记录字符串
|
|
*/
|
|
public function buildStrategyRecord(string $strategy, string $prefix = '', int $random_length = 4): string
|
|
{
|
|
return match ($strategy) {
|
|
'prefix' => "prefix:{$prefix}",
|
|
'prefix_random' => "prefix_random:{$prefix}:{$random_length}",
|
|
'manual' => 'manual',
|
|
default => $strategy,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 检查某个 origin_sku 在指定平台下是否已存在映射记录
|
|
*
|
|
* @return array{has_duplicate: bool, existing_mappings: array, message: string}
|
|
*/
|
|
public function checkDuplicate(int $origin_sku_id, int $platform_id): array
|
|
{
|
|
$existing = SkuMapping::query()
|
|
->where('origin_sku_id', $origin_sku_id)
|
|
->where('platform_id', $platform_id)
|
|
->where('enabled', true)
|
|
->get(['id', 'store_id', 'platform_outer_sku', 'note']);
|
|
|
|
$has_duplicate = $existing->isNotEmpty();
|
|
|
|
$message = $has_duplicate
|
|
? "该 origin_sku 在当前平台下已有 {$existing->count()} 条映射记录,可直接复用已有的 platform_outer_sku"
|
|
: '';
|
|
|
|
return [
|
|
'has_duplicate' => $has_duplicate,
|
|
'existing_mappings' => $existing->toArray(),
|
|
'message' => $message,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 唯一性检查:匹配数据库新唯一索引 (origin_sku_id, platform_id, platform_outer_sku)
|
|
*
|
|
* 用于 create/update 前的预检,避免击中索引冲突返回 500
|
|
*/
|
|
public function isUniqueMapping(
|
|
int $origin_sku_id,
|
|
int $platform_id,
|
|
string $platform_outer_sku,
|
|
?int $exclude_id = null,
|
|
): bool {
|
|
$query = SkuMapping::query()
|
|
->where('origin_sku_id', $origin_sku_id)
|
|
->where('platform_id', $platform_id)
|
|
->where('platform_outer_sku', $platform_outer_sku);
|
|
|
|
if ($exclude_id !== null) {
|
|
$query->where('id', '!=', $exclude_id);
|
|
}
|
|
|
|
return !$query->exists();
|
|
}
|
|
|
|
/**
|
|
* 读取 skus_origin.sku,用作 skus_mapping.origin_sku 快照值
|
|
*/
|
|
public function autoFillOriginSku(int $origin_sku_id): ?string
|
|
{
|
|
return SkuOrigin::query()->find($origin_sku_id)?->sku;
|
|
}
|
|
|
|
/**
|
|
* 检查 origin_sku 是否有映射引用(用于删除前检查)
|
|
*/
|
|
public function hasReferences(int $origin_sku_id): bool
|
|
{
|
|
return SkuMapping::query()
|
|
->where('origin_sku_id', $origin_sku_id)
|
|
->exists();
|
|
}
|
|
}
|