Files
MrleeAdmin/backend/plugin/article/app/service/admin/ContentService.php
T

130 lines
4.6 KiB
PHP
Raw Normal View History

2026-08-31 13:16:46 +08:00
<?php
declare(strict_types=1);
namespace plugin\article\app\service\admin;
use core\exception\handler\AdminException;
use madong\helper\PropertyCopier;
use core\base\BaseService;
use core\uuid\Snowflake;
use Illuminate\Support\Str;
use plugin\article\app\dao\ContentDao;
use plugin\article\app\model\Content;
use support\Db;
class ContentService extends BaseService
{
public function __construct(ContentDao $dao)
{
$this->dao = $dao;
}
public function save(array $data): ?\plugin\article\app\model\Content
{
try {
return $this->transaction(function () use ($data) {
$payload = $this->normalizePayload($data);
$tagIds = $payload['tag_ids'] ?? [];
unset($payload['tag_ids']);
$model = new Content();
PropertyCopier::copyProperties((object) $payload, $model);
$model->save();
$this->syncTags($model, $tagIds);
return $model->refresh()?->load(['category', 'tags', 'createds', 'updateds']);
});
} catch (\Throwable $e) {
throw new AdminException($e->getMessage());
}
}
public function update($id, $data): void
{
try {
$this->transaction(function () use ($id, $data) {
$model = $this->dao->get($id);
if (!$model) {
throw new AdminException('内容不存在');
}
$payload = $this->normalizePayload($data, false);
$tagIds = $payload['tag_ids'] ?? null;
unset($payload['tag_ids']);
PropertyCopier::copyProperties((object) $payload, $model);
$model->save();
if ($tagIds !== null) {
$this->syncTags($model, $tagIds);
}
});
} catch (\Throwable $e) {
throw new AdminException($e->getMessage());
}
}
protected function normalizePayload(array $data, bool $isCreate = true): array
{
$payload = $data;
$payload['content_type'] = $payload['content_type'] ?? 'article';
$payload['channel'] = $payload['channel'] ?? 'official';
$payload['visibility'] = isset($payload['visibility']) ? (int) $payload['visibility'] : 1;
$payload['source'] = $payload['source'] ?? 'original';
$payload['status'] = isset($payload['status']) ? (int) $payload['status'] : 0;
$payload['is_top'] = isset($payload['is_top']) ? (int) $payload['is_top'] : 0;
$payload['is_recommend'] = isset($payload['is_recommend']) ? (int) $payload['is_recommend'] : 0;
$payload['allow_comment'] = isset($payload['allow_comment']) ? (int) $payload['allow_comment'] : 1;
$payload['sort'] = isset($payload['sort']) ? (int) $payload['sort'] : 100;
$payload['view_count'] = isset($payload['view_count']) ? (int) $payload['view_count'] : 0;
$payload['like_count'] = isset($payload['like_count']) ? (int) $payload['like_count'] : 0;
$payload['comment_count'] = isset($payload['comment_count']) ? (int) $payload['comment_count'] : 0;
$payload['favorite_count'] = isset($payload['favorite_count']) ? (int) $payload['favorite_count'] : 0;
$payload['category_id'] = isset($payload['category_id']) ? (int) $payload['category_id'] : 0;
if (!empty($payload['slug'])) {
$payload['slug'] = trim((string) $payload['slug']);
} elseif ($isCreate && !empty($payload['title'])) {
$payload['slug'] = Str::slug((string) $payload['title']);
}
if (array_key_exists('tag_ids', $payload)) {
$payload['tag_ids'] = collect($payload['tag_ids'] ?? [])
->filter(static fn($id) => $id !== null && $id !== '' && $id !== 0 && $id !== '0')
->map(static fn($id) => (int) $id)
->unique()
->values()
->all();
}
return $payload;
}
protected function syncTags(Content $model, array $tagIds): void
{
$tableName = $model->tags()->getTable();
Db::table($tableName)->where('content_id', $model->id)->delete();
if (empty($tagIds)) {
return;
}
$now = time();
$rows = [];
foreach ($tagIds as $tagId) {
$rows[] = [
'id' => (string) Snowflake::generate(),
'content_id' => $model->id,
'tag_id' => (int) $tagId,
'created_at' => $now,
];
}
Db::table($tableName)->insert($rows);
}
}