where('type', 'article'); if ($category_id) { $model = $model->where('category_id', $category_id); } $list = $model->order('id', 'desc')->paginate($limit); $user_id = $this->getCurrentUserId(); $list->each(function ($item) use ($user_id) { $item->is_read = $user_id ? $this->getReadStatus($item->id, $user_id) : 0; return $item; }); return $this->success(__('successful'), $list->toArray()); } /** * faq * @Apidoc\method("GET") * @Apidoc\Query("page", type="int", require=true, desc="页码", default=1) * @Apidoc\Query("limit", type="int", require=true, desc="分页大小", default=10) */ public function faq() { $limit = (int)input('limit', 10); $list = ArchivesModel::alias('a') ->join('content c', 'a.id = c.id') ->where('a.status', 'normal') ->where('a.type', 'article') ->where('a.category_id', 9) ->field('a.title, a.id, c.content') ->order('a.id', 'desc') ->paginate($limit); return $this->success(__('successful'), $list->toArray()); } /** * 详情 * @Apidoc\Method("GET") * @Apidoc\Query("id", type="int", require=true, desc="ID") */ public function detail() { $id = (int)input('id'); if (!$id) { return $this->error(__("Invalid parameter")); } $vo = ArchivesModel::where('id', $id)->find(); if (!$vo) { return $this->error(__("Article does not exist")); } $this->appendContent($vo); $user_id = $this->getCurrentUserId(); if ($user_id) { $this->markAsRead($vo->id, $user_id); } return $this->success(__('successful'), $vo->toArray()); } /** * 获取最新公告 * @Apidoc\Method("GET") */ public function last_notie() { $vo = ArchivesModel::where('type', 'article') ->where('status', 'normal') ->order('id', 'desc') ->find(); if (!$vo) { return $this->success(__("successful"), []); } $this->appendContent($vo); $user_id = $this->getCurrentUserId(); if ($user_id) { $this->markAsRead($vo->id, $user_id); } return $this->success(__('successful'), $vo->toArray()); } /** * 单页详情 * @Apidoc\Method("GET") * @Apidoc\Query("id", type="int", require=true, desc="ID") * @Apidoc\Query("name", type="string", require=true, desc="二选1") */ public function singpage() { $id = (int)input('id'); $name = input('name'); $vo = null; if ($name) { $vo = ArchivesModel::where('name', $name)->find(); } elseif ($id) { $vo = ArchivesModel::where('id', $id)->find(); } if (!$vo) { return $this->error(__("Article does not exist")); } $this->appendContent($vo); return $this->success(__('successful'), $vo->toArray()); } /** * 幻灯片 * @Apidoc\Query("id", type="int", require=true, desc="ID") */ public function slide() { $list = [ ['image' => domain() . '/storage/slide/1.jpg', 'title' => ''], ['image' => domain() . '/storage/slide/2.webp', 'title' => ''], ['image' => domain() . '/storage/slide/3.webp', 'title' => ''], ['image' => domain() . '/storage/slide/4.jpg', 'title' => ''], ]; return $this->success(__('successful'), $list); } /** * 设为已读 * @Apidoc\Query("id", type="int", require=true, desc="ID,多个逗号隔开") */ public function mask_as_read() { $ids = input('id'); $user_id = $this->getCurrentUserId(); if (!$user_id) { return $this->success(__('successful')); } $ids = array_filter(explode(',', $ids)); foreach ($ids as $id) { $this->markAsRead((int)$id, $user_id); } return $this->success(__('successful')); } /** * 获取当前用户ID */ protected function getCurrentUserId(): int { try { return (int)JwtToken::getCurrentId(); } catch (\Throwable $e) { return 0; } } /** * 获取阅读状态 */ protected function getReadStatus(int $articleId, int $userId): int { return (int)(cache_get($this->getCacheKey($articleId, $userId)) ?: 0); } /** * 标记为已读 */ protected function markAsRead(int $articleId, int $userId = null): void { if (!$articleId) { return; } if (!$userId) { $userId = $this->getCurrentUserId(); } if (!$userId) { return; } $cacheKey = $this->getCacheKey($articleId, $userId); if (!cache_get($cacheKey)) { Db::name('archives_read')->insert([ 'user_id' => $userId, 'source_id' => $articleId, 'value' => 1 ]); cache($cacheKey, 1, self::CACHE_TTL); } } /** * 追加内容到文章 */ protected function appendContent(ArchivesModel $article): void { $content = Content::where('id', $article->id)->find(); if ($content) { $article->setAddonData($content->toArray()); } } /** * 生成缓存键 */ protected function getCacheKey(int $articleId, int $userId): string { return self::CACHE_PREFIX_READ . $articleId . '_' . $userId; } }