Files
qztool/backend/app/Http/Controllers/Api/V1/Admin/ContentController.php
T
DevandCursor 60daff2365 搭建轻舟一期门户、后台和统一登录。
让分类、会员和示例工具共用同一账号,本地即可跑通登录与授权。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-09 16:46:35 +08:00

167 lines
5.4 KiB
PHP

<?php
namespace App\Http\Controllers\Api\V1\Admin;
use App\Http\Controllers\Controller;
use App\Models\Agreement;
use App\Models\Article;
use App\Models\Banner;
use App\Models\Navigation;
use App\Support\HtmlSanitizer;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
class ContentController extends Controller
{
public function articles()
{
return $this->ok(Article::query()->latest('id')->limit(100)->get());
}
public function storeArticle(Request $request)
{
$article = Article::query()->create($this->articleData($request));
$this->audit($request->user(), 'article.create', $article, '新建文章 '.$article->title);
return $this->ok($article);
}
public function updateArticle(Request $request, Article $article)
{
$data = $this->articleData($request, $article->id);
if ($data['status'] === 'published' && ! $article->published_at) {
$data['published_at'] = now();
}
$article->update($data);
$this->audit($request->user(), 'article.update', $article, '更新文章 '.$article->title);
return $this->ok($article);
}
public function destroyArticle(Request $request, Article $article)
{
$article->delete();
$this->audit($request->user(), 'article.delete', $article, '删除文章 '.$article->title);
return $this->ok(null, '已删除');
}
public function banners()
{
return $this->ok(Banner::query()->orderByDesc('sort')->get());
}
public function storeBanner(Request $request)
{
$banner = Banner::query()->create($this->bannerData($request));
$this->audit($request->user(), 'banner.create', $banner, '新建轮播 '.$banner->title);
return $this->ok($banner);
}
public function updateBanner(Request $request, Banner $banner)
{
$banner->update($this->bannerData($request));
$this->audit($request->user(), 'banner.update', $banner, '更新轮播 '.$banner->title);
return $this->ok($banner);
}
public function destroyBanner(Request $request, Banner $banner)
{
$banner->delete();
$this->audit($request->user(), 'banner.delete', $banner, '删除轮播 '.$banner->title);
return $this->ok(null, '已删除');
}
public function navigations()
{
return $this->ok(Navigation::query()->orderBy('group_name')->orderByDesc('sort')->get());
}
public function storeNavigation(Request $request)
{
$item = Navigation::query()->create($this->navData($request));
$this->audit($request->user(), 'nav.create', $item, '新建导航 '.$item->title);
return $this->ok($item);
}
public function updateNavigation(Request $request, Navigation $navigation)
{
$navigation->update($this->navData($request));
$this->audit($request->user(), 'nav.update', $navigation, '更新导航 '.$navigation->title);
return $this->ok($navigation);
}
public function destroyNavigation(Request $request, Navigation $navigation)
{
$navigation->delete();
$this->audit($request->user(), 'nav.delete', $navigation, '删除导航 '.$navigation->title);
return $this->ok(null, '已删除');
}
public function agreements()
{
return $this->ok(Agreement::query()->orderBy('type')->get());
}
public function updateAgreement(Request $request, Agreement $agreement)
{
$data = $request->validate([
'title' => ['required', 'string', 'max:120'],
'body' => ['required', 'string'],
]);
$data['body'] = HtmlSanitizer::clean($data['body']);
$agreement->update($data);
$this->audit($request->user(), 'agreement.update', $agreement, '更新协议 '.$agreement->title);
return $this->ok($agreement);
}
private function articleData(Request $request, ?int $id = null): array
{
$data = $request->validate([
'type' => ['required', 'in:help,announcement,page'],
'title' => ['required', 'string', 'max:160'],
'slug' => ['required', 'regex:/^[a-z0-9]+(?:-[a-z0-9]+)*$/', Rule::unique('articles', 'slug')->ignore($id)],
'summary' => ['nullable', 'string', 'max:255'],
'body' => ['required', 'string'],
'status' => ['required', 'in:draft,published'],
]);
$data['body'] = HtmlSanitizer::clean($data['body']);
if ($data['status'] === 'published') {
$data['published_at'] = now();
}
return $data;
}
private function bannerData(Request $request): array
{
return $request->validate([
'title' => ['required', 'string', 'max:120'],
'image' => ['nullable', 'string', 'max:500'],
'link' => ['nullable', 'string', 'max:500'],
'sort' => ['nullable', 'integer'],
'starts_at' => ['nullable', 'date'],
'ends_at' => ['nullable', 'date'],
'status' => ['required', 'in:published,hidden'],
]);
}
private function navData(Request $request): array
{
return $request->validate([
'group_name' => ['required', 'in:header,footer'],
'title' => ['required', 'string', 'max:80'],
'link' => ['required', 'string', 'max:500'],
'sort' => ['nullable', 'integer'],
'status' => ['required', 'in:published,hidden'],
]);
}
}