feat: restore postcreate.js

This commit is contained in:
yanghao05
2025-04-18 15:03:20 +08:00
parent ac65302601
commit d81111226e
3 changed files with 10 additions and 69 deletions

View File

@@ -20,4 +20,8 @@ export const mediaService = {
uploadedSuccess(data) {
return httpClient.post('/admin/uploads/post-uploaded-action', data);
},
getMediaPreviewUrl(id) {
return `${httpClient.defaults.baseURL}/admin/medias/${id}`;
},
};

View File

@@ -30,7 +30,6 @@ const post = reactive({
selectedMedia: [],
medias: [],
status: 0,
head_image: null, // Add head image field
});
// Validation state
@@ -38,8 +37,7 @@ const errors = reactive({
title: '',
introduction: '',
selectedMedia: '',
discount: '',
head_image: '', // Add head image error field
discount: ''
});
// Media selection dialog state
@@ -48,7 +46,6 @@ const selectedMediaItems = ref([]);
const mediaLoading = ref(false);
const mediaGlobalFilter = ref('');
const mediaItems = ref([]);
const isHeadImageSelection = ref(false); // Track if we're selecting head image
// Add pagination state for media dialog
const mediaFirst = ref(0);
@@ -66,18 +63,8 @@ const statusOptions = [
{ label: '草稿', value: 0 }
];
// Open media selection dialog for head image
const openHeadImageDialog = () => {
isHeadImageSelection.value = true;
mediaDialogVisible.value = true;
mediaCurrentPage.value = 1;
mediaFirst.value = 0;
loadMediaItems();
};
// Open media selection dialog
const openMediaDialog = () => {
isHeadImageSelection.value = false;
mediaDialogVisible.value = true;
mediaCurrentPage.value = 1;
mediaFirst.value = 0;
@@ -112,16 +99,10 @@ const onMediaPage = (event) => {
// Confirm media selection
const confirmMediaSelection = () => {
if (isHeadImageSelection.value) {
if (selectedMediaItems.value.length) {
post.head_image = selectedMediaItems.value[0];
errors.head_image = '';
}
} else if (selectedMediaItems.value.length) {
post.selectedMedia = [...selectedMediaItems.value];
errors.selectedMedia = '';
}
selectedMediaItems.value = [];
mediaDialogVisible.value = false;
};
@@ -138,11 +119,6 @@ const removeMedia = (media) => {
}
};
// Remove head image
const removeHeadImage = () => {
post.head_image = null;
};
// Save the post
const savePost = async () => {
// Reset errors
@@ -173,19 +149,13 @@ const savePost = async () => {
valid = false;
}
if (!post.head_image) {
errors.head_image = '请选择封面图片';
valid = false;
}
if (!valid) {
toast.add({ severity: 'error', summary: '表单错误', detail: '请检查表单中的错误并修正', life: 3000 });
return;
}
try {
post.medias = post.selectedMedia.map(media => media.id);
post.head_image_id = post.head_image.id; // Add head image ID to submission
post.medias = post.selectedMedia.map(media => media.id)
const resp = await postService.createPost(post);
console.log(resp)
@@ -259,34 +229,6 @@ const formatFileSize = (bytes) => {
<div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Head Image -->
<div class="col-span-2">
<label class="block text-sm font-medium text-gray-700 mb-1">封面图片</label>
<div class="p-4 border border-gray-200 rounded-md">
<div v-if="!post.head_image" class="flex justify-center items-center flex-col space-y-3 py-6">
<i class="pi pi-image text-gray-400 text-5xl!"></i>
<p class="text-gray-500">请选择封面图片</p>
<Button label="选择图片" icon="pi pi-plus" @click="openHeadImageDialog" outlined />
<small v-if="errors.head_image" class="text-red-500">{{ errors.head_image }}</small>
</div>
<div v-else class="relative">
<div class="flex items-center">
<img :src="post.head_image.thumbnailUrl" class="w-32 h-32 object-cover rounded mr-4"
:alt="post.head_image.name">
<div class="flex flex-col">
<span class="font-medium">{{ post.head_image.name }}</span>
<div class="flex gap-2 mt-2">
<Button label="更换图片" icon="pi pi-sync" @click="openHeadImageDialog" outlined
size="small" />
<Button label="移除" icon="pi pi-times" severity="danger" outlined size="small"
@click="removeHeadImage" />
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Title -->
<div class="col-span-2">
<label for="title" class="block text-sm font-medium text-gray-700 mb-1">标题</label>
@@ -374,15 +316,15 @@ const formatFileSize = (bytes) => {
</div>
<!-- Media Selection Dialog -->
<Dialog v-model:visible="mediaDialogVisible" :header="isHeadImageSelection ? '选择封面图片' : '选择媒体'" :modal="true"
:dismissableMask="true" :closable="true" :style="{ width: '80vw' }" :breakpoints="{ '960px': '90vw' }">
<Dialog v-model:visible="mediaDialogVisible" header="选择媒体" :modal="true" :dismissableMask="true" :closable="true"
:style="{ width: '80vw' }" :breakpoints="{ '960px': '90vw' }">
<div class="mb-4">
<InputText v-model="mediaGlobalFilter" placeholder="搜索媒体..." class="w-full" />
</div>
<DataTable v-model:selection="selectedMediaItems" :value="mediaItems" :loading="mediaLoading" dataKey="id"
:paginator="true" v-model:first="mediaFirst" v-model:rows="mediaRows" :totalRecords="mediaTotalRecords"
@page="onMediaPage" :selectionMode="isHeadImageSelection ? 'single' : 'multiple'"
@page="onMediaPage" selectionMode="multiple"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport"
:rows-per-page-options="[10, 25, 50]" currentPageReportTemplate="第 {first} 到 {last} 条,共 {totalRecords} 条"
:lazy="true" :showCurrentPageReport="true">

View File

@@ -1,4 +1,3 @@
import { useAuthStore } from '@/stores/auth';
import axios from 'axios';
// Create axios instance with default config
@@ -13,10 +12,6 @@ const client = axios.create({
// Request interceptor
client.interceptors.request.use(
config => {
const authStore = useAuthStore();
if (authStore.isAuthenticated && authStore.token) {
config.headers.Authorization = `Bearer ${authStore.token}`;
}
return config;
},
error => {