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