Files
Leantime/app/Domain/Bom/Services/MasterRef.php

153 lines
4.3 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Leantime\Domain\Bom\Services;
use Leantime\Core\Domains\BaseService;
use Leantime\Domain\Bom\Permissions\BomPermissions;
use Leantime\Domain\Bom\Repositories\Bom as BomRepository;
use Leantime\Domain\Bom\Repositories\MasterRef as MasterRefRepository;
/**
* 项目 ↔ 全局主数据BOM/工艺文件/工具清单)引用服务。
*
* 单向引用:项目引用主数据后追加的项目级列/值只存引用层,绝不写回全局主数据。
*/
class MasterRef extends BaseService
{
public function __construct(
protected MasterRefRepository $repo,
protected BomRepository $bomRepo,
) {}
/**
* 项目已引用的主数据列表。
*/
public function getRefs(int $projectId): array
{
return $this->repo->getRefsByProject($projectId);
}
/**
* 项目引用一个主数据(幂等:已引用则返回已有 refId
*/
public function link(int $projectId, int $masterId): int
{
$this->authorize(BomPermissions::EDIT, $projectId);
$master = $this->bomRepo->getBom($masterId);
if ($master === false) {
return 0;
}
$existing = $this->repo->findRef($projectId, $masterId);
if ($existing !== false) {
return (int) $existing['id'];
}
return $this->repo->createRef([
'projectId' => $projectId,
'masterId' => $masterId,
'createdOn' => now(),
]);
}
public function unlink(int $refId): bool
{
$ref = $this->repo->getRef($refId);
if ($ref === false) {
return false;
}
$this->authorize(BomPermissions::EDIT, (int) $ref['projectId']);
return $this->repo->deleteRef($refId);
}
/**
* 项目级引用详情:主数据明细 + 项目级追加列 + 项目级追加值。
*/
public function getRefDetail(int $refId): array|false
{
$ref = $this->repo->getRef($refId);
if ($ref === false) {
return false;
}
$this->authorize(BomPermissions::VIEW, (int) $ref['projectId']);
$columns = $this->repo->getColumns($refId);
$values = $this->repo->getValues($refId);
// 值按 itemId -> [columnId -> value] 组织
$valueMap = [];
foreach ($values as $v) {
$valueMap[(int) $v['itemId']][(int) $v['columnId']] = (string) $v['value'];
}
return [
'ref' => $ref,
'columns' => $columns,
'values' => $valueMap,
];
}
/**
* 项目级追加列。
*/
public function addColumn(int $refId, string $key, string $label): int
{
$ref = $this->repo->getRef($refId);
if ($ref === false) {
return 0;
}
$this->authorize(BomPermissions::EDIT, (int) $ref['projectId']);
$key = trim(str_replace([' ', '/', '\\'], '_', $key));
if ($key === '') {
return 0;
}
foreach ($this->repo->getColumns($refId) as $col) {
if ($col['key'] === $key) {
return (int) $col['id'];
}
}
$maxSort = 0;
foreach ($this->repo->getColumns($refId) as $col) {
$maxSort = max($maxSort, (int) $col['sortOrder']);
}
return $this->repo->addColumn([
'refId' => $refId,
'key' => $key,
'label' => trim($label) ?: $key,
'sortOrder' => $maxSort + 1,
]);
}
public function deleteColumn(int $columnId): bool
{
// 按 columnId 找 refId 以完成鉴权
$ref = $this->repo->getRefByColumnId($columnId);
if ($ref === false) {
return false;
}
$this->authorize(BomPermissions::EDIT, (int) $ref['projectId']);
return $this->repo->deleteColumn($columnId);
}
/**
* 保存项目级追加值(不影响全局主数据)。
*/
public function saveValue(int $refId, int $columnId, int $itemId, string $value): bool
{
$ref = $this->repo->getRef($refId);
if ($ref === false) {
return false;
}
$this->authorize(BomPermissions::EDIT, (int) $ref['projectId']);
return $this->repo->setValue($refId, $columnId, $itemId, $value);
}
}