Files
xin-procurement/app/Models/ProductCategoryModel.php
T
2026-09-04 22:10:28 +08:00

131 lines
3.4 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* 商品分类模型(蔬菜/水果/其他,多级分类自关联)
*/
class ProductCategoryModel extends Model
{
/** 状态:停用 */
public const int STATUS_DISABLED = 0;
/** 状态:正常 */
public const int STATUS_NORMAL = 1;
protected $table = 'product_category';
protected $primaryKey = 'id';
protected $fillable = [
'parent_id',
'name',
'sort',
'status'
];
protected $casts = [
'parent_id' => 'integer',
'sort' => 'integer',
'status' => 'integer',
'created_at' => 'datetime:Y-m-d H:i:s',
'updated_at' => 'datetime:Y-m-d H:i:s',
];
/**
* 父分类
*/
public function parent(): BelongsTo
{
return $this->belongsTo(self::class, 'parent_id', 'id');
}
/**
* 子分类
*/
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id', 'id')->orderBy('sort');
}
/**
* 分类下的商品
*/
public function products(): HasMany
{
return $this->hasMany(ProductModel::class, 'category_id', 'id');
}
/**
* 获取分类树(树表展示 / 级联下拉选项复用)
*
* @param bool $onlyEnabled 是否仅返回启用分类
* @return array<int, array{id: int, name: string, parent_id: int, sort: int, status: int, children?: array}>
*/
public static function getTreeData($columns = ['*'], bool $onlyEnabled = false): array
{
$query = static::query()->orderBy('sort')->orderBy('id');
if ($onlyEnabled) {
$query->where('status', self::STATUS_NORMAL);
}
return static::buildTree($query->get($columns)->toArray());
}
/**
* 按树展示顺序(sort/id 深度优先)获取分类 ID 列表,供商品列表等按分类顺序排序
*
* @param bool $onlyEnabled 是否仅包含启用分类
* @return array<int, int>
*/
public static function getTreeOrderedIds(bool $onlyEnabled = false): array
{
return static::flattenTreeIds(static::getTreeData(['id', 'parent_id'], $onlyEnabled));
}
/**
* 深度优先展开分类树为有序 ID 列表
*
* @param array<int, array<string, mixed>> $tree
* @return array<int, int>
*/
private static function flattenTreeIds(array $tree): array
{
$ids = [];
foreach ($tree as $node) {
$ids[] = (int) $node['id'];
if (!empty($node['children'])) {
$ids = [...$ids, ...static::flattenTreeIds($node['children'])];
}
}
return $ids;
}
/**
* 将扁平分类列表组装为树
*
* @param array<int, array<string, mixed>> $items
* @param int $parentId
* @return array<int, array<string, mixed>>
*/
public static function buildTree(array $items, int $parentId = 0): array
{
$tree = [];
foreach ($items as $item) {
if ((int) $item['parent_id'] !== $parentId) {
continue;
}
$children = static::buildTree($items, (int) $item['id']);
if ($children !== []) {
$item['children'] = $children;
}
$tree[] = $item;
}
return $tree;
}
}