Changes
This commit is contained in:
@@ -21,9 +21,10 @@ class PublishPostAction
|
|||||||
* Публикует черновик поста
|
* Публикует черновик поста
|
||||||
*
|
*
|
||||||
* @param Post $post Пост для публикации
|
* @param Post $post Пост для публикации
|
||||||
|
* @param bool $publishToVk Публиковать ли в VK
|
||||||
* @return Post Опубликованный пост
|
* @return Post Опубликованный пост
|
||||||
*/
|
*/
|
||||||
public function run(Post $post): Post
|
public function run(Post $post, bool $publishToVk = true): Post
|
||||||
{
|
{
|
||||||
// Обновляем данные поста
|
// Обновляем данные поста
|
||||||
$updatedData = $this->postDataProcessor->processUpdate([
|
$updatedData = $this->postDataProcessor->processUpdate([
|
||||||
@@ -40,8 +41,10 @@ class PublishPostAction
|
|||||||
// Отправляем уведомления
|
// Отправляем уведомления
|
||||||
$this->sendNotifications($post);
|
$this->sendNotifications($post);
|
||||||
|
|
||||||
// Публикуем в VK
|
// Публикуем в VK, если указано
|
||||||
$this->publishToVk($post);
|
if ($publishToVk) {
|
||||||
|
$this->publishToVk($post);
|
||||||
|
}
|
||||||
|
|
||||||
// Обновляем слайд, если есть
|
// Обновляем слайд, если есть
|
||||||
$this->updateSlide($post);
|
$this->updateSlide($post);
|
||||||
|
|||||||
@@ -95,9 +95,12 @@ class CreatePostFromAiDataTask
|
|||||||
*/
|
*/
|
||||||
private function preparePostData(array $newsData, array $content, ?string $previewPath, array $imagesPaths): array
|
private function preparePostData(array $newsData, array $content, ?string $previewPath, array $imagesPaths): array
|
||||||
{
|
{
|
||||||
|
$baseSlug = Str::slug($newsData['title'] ?? '');
|
||||||
|
$slug = $this->generateUniqueSlug($baseSlug);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'title' => $newsData['title'] ?? 'Без названия',
|
'title' => $newsData['title'] ?? 'Без названия',
|
||||||
'slug' => Str::slug($newsData['title'] ?? '') . '-' . time(),
|
'slug' => $slug,
|
||||||
'content' => $content,
|
'content' => $content,
|
||||||
'authors' => $newsData['authors'] ?? [],
|
'authors' => $newsData['authors'] ?? [],
|
||||||
'category_id' => $newsData['category_id'] ?? null,
|
'category_id' => $newsData['category_id'] ?? null,
|
||||||
@@ -113,6 +116,22 @@ class CreatePostFromAiDataTask
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Генерирует уникальный slug
|
||||||
|
*/
|
||||||
|
private function generateUniqueSlug(string $baseSlug): string
|
||||||
|
{
|
||||||
|
$slug = $baseSlug;
|
||||||
|
$count = 1;
|
||||||
|
|
||||||
|
while (Post::where('slug', $slug)->exists()) {
|
||||||
|
$slug = $baseSlug . '-' . $count;
|
||||||
|
$count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $slug;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сохраняет теги поста
|
* Сохраняет теги поста
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class PublishPostController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$publishedPost = $this->publishPostAction->run($post);
|
$publishedPost = $this->publishPostAction->run($post, $request->input('publish_to_vk', true));
|
||||||
|
|
||||||
return back()->with([
|
return back()->with([
|
||||||
'success' => 'Новость успешно опубликована: ' . $publishedPost->title,
|
'success' => 'Новость успешно опубликована: ' . $publishedPost->title,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class CreateVkPost implements ShouldQueue
|
|||||||
readonly private array $images = [],
|
readonly private array $images = [],
|
||||||
readonly private int $post_id,
|
readonly private int $post_id,
|
||||||
readonly private int|null $publish_date = null,
|
readonly private int|null $publish_date = null,
|
||||||
|
readonly private string $primary_attachments_mode = 'carousel',
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -34,7 +34,13 @@ class CreateVkPost implements ShouldQueue
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$vkService = new VkService();
|
$vkService = new VkService();
|
||||||
$vk_post = $vkService->createPost($this->title, $this->text, $this->images, $this->publish_date);
|
$vk_post = $vkService->createPost(
|
||||||
|
$this->title,
|
||||||
|
$this->text,
|
||||||
|
$this->images,
|
||||||
|
$this->publish_date,
|
||||||
|
$this->primary_attachments_mode
|
||||||
|
);
|
||||||
DB::table('posts_vk_posts')->insert(
|
DB::table('posts_vk_posts')->insert(
|
||||||
[
|
[
|
||||||
'post_id' => $this->post_id,
|
'post_id' => $this->post_id,
|
||||||
|
|||||||
@@ -28,9 +28,10 @@ class CreateVkPostJob implements ShouldQueue
|
|||||||
protected $videos;
|
protected $videos;
|
||||||
protected $publish_date;
|
protected $publish_date;
|
||||||
protected $public_id;
|
protected $public_id;
|
||||||
|
protected $primary_attachments_mode;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
int $post_id, string $title, string $message, array $images = [], array $videos = [], ?int $publish_date = null
|
int $post_id, string $title, string $message, array $images = [], array $videos = [], ?int $publish_date = null, string $primary_attachments_mode = 'carousel'
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$this->post_id = $post_id;
|
$this->post_id = $post_id;
|
||||||
@@ -40,6 +41,7 @@ class CreateVkPostJob implements ShouldQueue
|
|||||||
$this->videos = $videos;
|
$this->videos = $videos;
|
||||||
$this->publish_date = $publish_date;
|
$this->publish_date = $publish_date;
|
||||||
$this->public_id = config('services.vk.public_id');
|
$this->public_id = config('services.vk.public_id');
|
||||||
|
$this->primary_attachments_mode = $primary_attachments_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle()
|
public function handle()
|
||||||
@@ -96,7 +98,7 @@ class CreateVkPostJob implements ShouldQueue
|
|||||||
$attachmentString = implode(',', $selected_attachments);
|
$attachmentString = implode(',', $selected_attachments);
|
||||||
Log::info("{$logPrefix} Финальная строка вложений: '{$attachmentString}'");
|
Log::info("{$logPrefix} Финальная строка вложений: '{$attachmentString}'");
|
||||||
|
|
||||||
$vk_post = $wallService->createPost($this->message, $from_group, $attachmentString, $this->publish_date);
|
$vk_post = $wallService->createPost($this->message, $from_group, $attachmentString, $this->publish_date, $this->primary_attachments_mode);
|
||||||
|
|
||||||
if (isset($vk_post['post_id'])) {
|
if (isset($vk_post['post_id'])) {
|
||||||
Log::info("{$logPrefix} Пост успешно создан ID: {$vk_post['post_id']}");
|
Log::info("{$logPrefix} Пост успешно создан ID: {$vk_post['post_id']}");
|
||||||
|
|||||||
@@ -28,9 +28,10 @@ class UpdateVkPostJob implements ShouldQueue
|
|||||||
protected $videos;
|
protected $videos;
|
||||||
protected $publish_date;
|
protected $publish_date;
|
||||||
protected $public_id;
|
protected $public_id;
|
||||||
|
protected $primary_attachments_mode;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
int $post_id, string $title, string $message, array $images = [], array $videos = [], ?int $publish_date = null
|
int $post_id, string $title, string $message, array $images = [], array $videos = [], ?int $publish_date = null, string $primary_attachments_mode = 'carousel'
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$this->post_id = $post_id;
|
$this->post_id = $post_id;
|
||||||
@@ -40,6 +41,7 @@ class UpdateVkPostJob implements ShouldQueue
|
|||||||
$this->videos = $videos;
|
$this->videos = $videos;
|
||||||
$this->publish_date = $publish_date;
|
$this->publish_date = $publish_date;
|
||||||
$this->public_id = config('services.vk.public_id');
|
$this->public_id = config('services.vk.public_id');
|
||||||
|
$this->primary_attachments_mode = $primary_attachments_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle()
|
public function handle()
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class VkService
|
|||||||
// return $this->wallService->createPost($message, $from_group, $attachmentString, $publish_date);
|
// return $this->wallService->createPost($message, $from_group, $attachmentString, $publish_date);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public function createPost(string $title, string $message, array $images = [], array $videos = [], int|null $publish_date = null)
|
public function createPost(string $title, string $message, array $images = [], array $videos = [], int|null $publish_date = null, string $primary_attachments_mode = 'carousel')
|
||||||
{
|
{
|
||||||
$from_group = 1;
|
$from_group = 1;
|
||||||
$attachments = [];
|
$attachments = [];
|
||||||
@@ -76,7 +76,7 @@ class VkService
|
|||||||
|
|
||||||
$attachmentString = implode(',', $attachments);
|
$attachmentString = implode(',', $attachments);
|
||||||
|
|
||||||
return $this->wallService->createPost($message, $from_group, $attachmentString, $publish_date);
|
return $this->wallService->createPost($message, $from_group, $attachmentString, $publish_date, $primary_attachments_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updatePost(int $id, string $title, string $message, array $images = [], int|null $publish_date = null)
|
public function updatePost(int $id, string $title, string $message, array $images = [], int|null $publish_date = null)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class VkWallService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createPost(string $message, int $from_group, string $attachments = '', int|null $publish_date = null)
|
public function createPost(string $message, int $from_group, string $attachments = '', int|null $publish_date = null, string $primary_attachments_mode = 'carousel')
|
||||||
{
|
{
|
||||||
$token = $this->vkAuthService->getToken()->access_token;
|
$token = $this->vkAuthService->getToken()->access_token;
|
||||||
$params = [
|
$params = [
|
||||||
@@ -58,6 +58,7 @@ class VkWallService
|
|||||||
'attachments' => $attachments,
|
'attachments' => $attachments,
|
||||||
'access_token' => $token,
|
'access_token' => $token,
|
||||||
'publish_date' => $publish_date,
|
'publish_date' => $publish_date,
|
||||||
|
'primary_attachments_mode' => $primary_attachments_mode,
|
||||||
'v' => '5.131',
|
'v' => '5.131',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,18 @@
|
|||||||
<span>Обновлено: {{ new Date(post.updated_at).toLocaleDateString('ru-RU') }}</span>
|
<span>Обновлено: {{ new Date(post.updated_at).toLocaleDateString('ru-RU') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4 flex flex-col gap-2">
|
<div class="ml-4 flex flex-col gap-2 items-end">
|
||||||
|
<!-- Переключатель публикации в VK -->
|
||||||
|
<label class="flex items-center gap-2 cursor-pointer mb-2" @click.stop>
|
||||||
|
<input
|
||||||
|
v-model="postPublishSettings[post.id]"
|
||||||
|
type="checkbox"
|
||||||
|
class="sr-only peer"
|
||||||
|
>
|
||||||
|
<div class="relative w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-indigo-300 rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-indigo-600"></div>
|
||||||
|
<span class="text-xs font-medium text-gray-600">VK</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@click.stop="publishPost(post)"
|
@click.stop="publishPost(post)"
|
||||||
:disabled="publishProcessing"
|
:disabled="publishProcessing"
|
||||||
@@ -297,7 +308,20 @@
|
|||||||
|
|
||||||
<!-- Кнопки действий -->
|
<!-- Кнопки действий -->
|
||||||
<div class="sticky bottom-0 bg-gray-50 border-t border-gray-200 px-6 py-4 flex justify-between items-center rounded-b-lg">
|
<div class="sticky bottom-0 bg-gray-50 border-t border-gray-200 px-6 py-4 flex justify-between items-center rounded-b-lg">
|
||||||
<div class="flex gap-3">
|
<div class="flex items-center gap-4">
|
||||||
|
<!-- Переключатель публикации в VK -->
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click.stop="postPublishSettings[selectedPost?.id] = !postPublishSettings[selectedPost?.id]"
|
||||||
|
class="flex items-center gap-2 cursor-pointer focus:outline-none"
|
||||||
|
>
|
||||||
|
<div class="relative">
|
||||||
|
<div class="w-11 h-6 bg-gray-200 rounded-full transition-colors" :class="postPublishSettings[selectedPost?.id] ? 'bg-indigo-600' : 'bg-gray-200'"></div>
|
||||||
|
<div class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full transition-transform" :class="postPublishSettings[selectedPost?.id] ? 'translate-x-5' : 'translate-x-0'"></div>
|
||||||
|
</div>
|
||||||
|
<span class="text-sm font-medium text-gray-700">Опубликовать в VK</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Кнопка "Опубликовать" (только для черновиков) -->
|
<!-- Кнопка "Опубликовать" (только для черновиков) -->
|
||||||
<button
|
<button
|
||||||
v-if="!selectedPost.publish_at"
|
v-if="!selectedPost.publish_at"
|
||||||
@@ -334,7 +358,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, watch } from 'vue';
|
||||||
import { useForm, usePage, router } from '@inertiajs/vue3';
|
import { useForm, usePage, router } from '@inertiajs/vue3';
|
||||||
|
|
||||||
// Сохраняем имя компонента
|
// Сохраняем имя компонента
|
||||||
@@ -352,6 +376,18 @@ const selectedPost = ref(null);
|
|||||||
// Состояние для процесса публикации
|
// Состояние для процесса публикации
|
||||||
const publishProcessing = ref(false);
|
const publishProcessing = ref(false);
|
||||||
|
|
||||||
|
// Состояние для переключателя публикации в VK (отдельно для каждого поста)
|
||||||
|
const postPublishSettings = ref({});
|
||||||
|
|
||||||
|
// Инициализируем переключатели для всех постов
|
||||||
|
watch(draftPosts, (posts) => {
|
||||||
|
posts.forEach(post => {
|
||||||
|
if (postPublishSettings.value[post.id] === undefined) {
|
||||||
|
postPublishSettings.value[post.id] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
// Открытие модального окна
|
// Открытие модального окна
|
||||||
const openPostModal = (post) => {
|
const openPostModal = (post) => {
|
||||||
selectedPost.value = post;
|
selectedPost.value = post;
|
||||||
@@ -370,7 +406,9 @@ const publishPost = (post) => {
|
|||||||
|
|
||||||
publishProcessing.value = true;
|
publishProcessing.value = true;
|
||||||
|
|
||||||
router.post(route('dashboard.posts.publish', post.id), {}, {
|
router.post(route('dashboard.posts.publish', post.id), {
|
||||||
|
publish_to_vk: postPublishSettings.value[post.id] ?? true,
|
||||||
|
}, {
|
||||||
preserveScroll: true,
|
preserveScroll: true,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
publishProcessing.value = false;
|
publishProcessing.value = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user