# Hyperf Service — 代码模板 > 主流程见 SKILL.md,本文档为 Service/Repository/Event/Logger/Retry 完整实现。 ## Service 模板 ```php repository->getPageList($params); } public function getById(int $id): {{Module}} { $record = {{Module}}::find($id); if (!$record) throw new BusinessException(404, '{{Module}} not found'); return $record; } public function create(array $data): {{Module}} { return Db::transaction(function () use ($data) { $record = {{Module}}::create($data); return $record; }); } public function update(int $id, array $data): {{Module}} { $record = $this->getById($id); return Db::transaction(function () use ($record, $data) { $record->update($data); return $record->refresh(); }); } public function delete(int $id): void { $record = $this->getById($id); Db::transaction(fn () => $record->delete()); } } ``` ## Repository 模板(含 applyFilters / applyDataScope) ```php class {{Module}}Repository { public function getPageList(array $params): array { $query = {{Module}}::query(); $this->applyFilters($query, $params); $this->applyDataScope($query); $page = (int) ($params['page'] ?? 1); $pageSize = min((int) ($params['page_size'] ?? 10), 100); $total = $query->count(); $items = $query->with($this->getDefaultRelations())->orderByDesc('id') ->offset(($page - 1) * $pageSize)->limit($pageSize)->get(); return ['items' => $items, 'total' => $total]; } protected function applyFilters(Builder $query, array $params): void { if (!empty($params['keyword'])) $query->where('name', 'like', "%{$params['keyword']}%"); if (!empty($params['status'])) $query->where('status', $params['status']); } protected function applyDataScope(Builder $query): void { /* 数据权限 */ } protected function getDefaultRelations(): array { return []; } } ``` ## Event + Listener 模板 ```php // Event class {{Module}}Created { public function __construct(public readonly {{Module}} $record) {} } // Listener #[Listener] class {{Module}}CreatedListener implements ListenerInterface { public function listen(): array { return [{{Module}}Created::class]; } public function process(object $event): void { /* 发送通知、更新缓存等 */ } } ``` ## HasLogger Trait ```php trait HasLogger { protected ?LoggerInterface $logger = null; protected function logger(): LoggerInterface { /* 按类名获取 channel */ } protected function logContext(array $extra = []): array { return array_merge(['request_id' => Context::get('request_id'), 'user_id' => Context::get('current_user_id')], $extra); } } ``` ## RetryHelper ```php public static function withRetry(callable $fn, int $maxRetries = 3, int $baseDelayMs = 1000, array $retryOn = []): mixed { for ($attempt = 0; $attempt <= $maxRetries; $attempt++) { try { return $fn(); } catch (\Throwable $e) { if ($attempt < $maxRetries) Coroutine::sleep(($baseDelayMs * (2 ** $attempt) + jitter) / 1000); else throw $e; } } } ``` ## RequestIdMiddleware 在 process 中:`Context::set('request_id', $requestId)`,响应头加 `X-Request-ID`。