feat(cms): sync site assets, revalidate webhook, and document download naming

This commit is contained in:
2026-02-10 23:38:31 +08:00
parent c4969cd4d2
commit b6e18a83ec
27 changed files with 1019 additions and 26 deletions

View File

@@ -0,0 +1,28 @@
<?php
namespace Database\Factories;
use App\Models\ArticleCategory;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* @extends Factory<ArticleCategory>
*/
class ArticleCategoryFactory extends Factory
{
protected $model = ArticleCategory::class;
public function definition(): array
{
$name = $this->faker->unique()->words(2, true);
return [
'name' => $name,
'slug' => Str::slug($name) ?: 'category-'.Str::random(8),
'description' => $this->faker->optional()->sentence(),
'sort_order' => $this->faker->numberBetween(0, 50),
];
}
}

View File

@@ -0,0 +1,79 @@
<?php
namespace Database\Factories;
use App\Models\Article;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* @extends Factory<Article>
*/
class ArticleFactory extends Factory
{
protected $model = Article::class;
public function definition(): array
{
$title = $this->faker->sentence(6);
$slug = Str::slug($title) ?: 'article-'.Str::random(10);
return [
'title' => $title,
'slug' => $slug,
'summary' => $this->faker->optional()->paragraph(),
'content' => $this->faker->paragraphs(5, true),
'content_type' => Article::CONTENT_TYPE_BLOG,
'status' => Article::STATUS_PUBLISHED,
'access_level' => Article::ACCESS_LEVEL_PUBLIC,
'featured_image_path' => null,
'featured_image_alt' => null,
'author_name' => $this->faker->optional()->name(),
'author_user_id' => null,
'meta_description' => $this->faker->optional()->sentence(),
'meta_keywords' => null,
'is_pinned' => false,
'display_order' => 0,
'published_at' => now()->subDay(),
'expires_at' => null,
'archived_at' => null,
'view_count' => 0,
'created_by_user_id' => User::factory(),
'last_updated_by_user_id' => User::factory(),
];
}
public function draft(): static
{
return $this->state(fn () => [
'status' => Article::STATUS_DRAFT,
'published_at' => null,
]);
}
public function pinned(int $order = 0): static
{
return $this->state(fn () => [
'is_pinned' => true,
'display_order' => $order,
]);
}
public function expired(): static
{
return $this->state(fn () => [
'status' => Article::STATUS_PUBLISHED,
'expires_at' => now()->subDay(),
]);
}
public function scheduled(): static
{
return $this->state(fn () => [
'status' => Article::STATUS_PUBLISHED,
'published_at' => now()->addDay(),
]);
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Database\Factories;
use App\Models\ArticleTag;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* @extends Factory<ArticleTag>
*/
class ArticleTagFactory extends Factory
{
protected $model = ArticleTag::class;
public function definition(): array
{
$name = $this->faker->unique()->words(2, true);
return [
'name' => $name,
'slug' => Str::slug($name) ?: 'tag-'.Str::random(8),
];
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Database\Factories;
use App\Models\Page;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* @extends Factory<Page>
*/
class PageFactory extends Factory
{
protected $model = Page::class;
public function definition(): array
{
$title = $this->faker->sentence(4);
$slug = Str::slug($title) ?: 'page-'.Str::random(10);
return [
'title' => $title,
'slug' => $slug,
'content' => $this->faker->paragraphs(6, true),
'template' => null,
'custom_fields' => null,
'status' => Page::STATUS_PUBLISHED,
'meta_description' => $this->faker->optional()->sentence(),
'meta_keywords' => null,
'parent_id' => null,
'sort_order' => 0,
'published_at' => now()->subDay(),
'created_by_user_id' => User::factory(),
'last_updated_by_user_id' => User::factory(),
];
}
public function draft(): static
{
return $this->state(fn () => [
'status' => Page::STATUS_DRAFT,
'published_at' => null,
]);
}
}