fix: create post

This commit is contained in:
yanghao05
2025-04-09 20:32:31 +08:00
parent 05d2ecc2b9
commit 2346983d67
10 changed files with 192 additions and 95 deletions

View File

@@ -1,5 +1,6 @@
<script setup>
import { mediaService } from '@/api/mediaService';
import { postService } from '@/api/postService';
import { useToast } from 'primevue/usetoast';
import { computed, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
@@ -24,16 +25,19 @@ const toast = useToast();
const post = reactive({
title: '',
price: 0,
discount: 100, // Add discount field with default value
introduction: '',
selectedMedia: [],
status: 'draft' // Add status field with default value
medias: [],
status: 0,
});
// Validation state
const errors = reactive({
title: '',
introduction: '',
selectedMedia: ''
selectedMedia: '',
discount: ''
});
// Media selection dialog state
@@ -55,8 +59,8 @@ const mediaTotalPages = computed(() => {
// Status options
const statusOptions = [
{ label: '发布', value: 'published' },
{ label: '草稿', value: 'draft' }
{ label: '发布', value: 1 },
{ label: '草稿', value: 0 }
];
// Open media selection dialog
@@ -75,8 +79,9 @@ const loadMediaItems = async () => {
page: mediaCurrentPage.value,
limit: mediaRows.value
});
mediaItems.value = response.items;
mediaTotalRecords.value = response.total;
console.log(response.data.items)
mediaItems.value = response.data.items;
mediaTotalRecords.value = response.data.total;
} catch (error) {
toast.add({ severity: 'error', summary: '错误', detail: '加载媒体文件失败', life: 3000 });
} finally {
@@ -118,6 +123,7 @@ const removeMedia = (media) => {
const savePost = async () => {
// Reset errors
Object.keys(errors).forEach(key => errors[key] = '');
console.log(post.value)
// Validate form
let valid = true;
@@ -137,18 +143,26 @@ const savePost = async () => {
valid = false;
}
// check discount
if (post.discount < 0 || post.discount > 100) {
errors.discount = '折扣必须在0到100之间';
valid = false;
}
if (!valid) {
toast.add({ severity: 'error', summary: '表单错误', detail: '请检查表单中的错误并修正', life: 3000 });
return;
}
try {
// In a real app, you would call an API to save the post
// await postApi.createPost(post);
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 1000));
post.medias = post.selectedMedia.map(media => media.id)
const resp = await postService.createPost(post);
console.log(resp)
if (resp.status !== 200) {
toast.add({ severity: 'error', summary: '错误', detail: resp.message, life: 3000 });
return;
}
toast.add({ severity: 'success', summary: '成功', detail: '文章已成功创建', life: 3000 });
// Navigate back to the post list
@@ -219,16 +233,23 @@ const formatFileSize = (bytes) => {
<div class="col-span-2">
<label for="title" class="block text-sm font-medium text-gray-700 mb-1">标题</label>
<InputText id="title" v-model="post.title" class="w-full p-inputtext-lg" placeholder="输入文章标题" />
<small v-if="errors.title" class="p-error">{{ errors.title }}</small>
<small v-if="errors.title" class="text-red-500">{{ errors.title }}</small>
</div>
<!-- Price -->
<div class="col-span-2">
<div class="col-span-1">
<label for="price" class="block text-sm font-medium text-gray-700 mb-1">价格 (¥)</label>
<InputNumber id="price" v-model="post.price" mode="currency" currency="CNY" :minFractionDigits="2"
class="w-full" />
</div>
<!-- Discount -->
<div class="col-span-1">
<label for="discount" class="block text-sm font-medium text-gray-700 mb-1">折扣 (%)</label>
<InputNumber id="discount" v-model="post.discount" :min="0" :max="100" :minFractionDigits="0"
:maxFractionDigits="0" class="w-full" placeholder="输入折扣百分比" />
</div>
<!-- Status -->
<div class="col-span-2">
<label class="block text-sm font-medium text-gray-700 mb-1">状态</label>
@@ -247,7 +268,7 @@ const formatFileSize = (bytes) => {
<label for="introduction" class="block text-sm font-medium text-gray-700 mb-1">文章介绍</label>
<Textarea id="introduction" v-model="post.introduction" rows="5" class="w-full"
placeholder="输入文章介绍内容" />
<small v-if="errors.introduction" class="p-error">{{ errors.introduction }}</small>
<small v-if="errors.introduction" class="text-red-500">{{ errors.introduction }}</small>
</div>
<!-- Media Selection -->
@@ -259,7 +280,7 @@ const formatFileSize = (bytes) => {
<i class="pi pi-image text-gray-400 text-5xl!"></i>
<p class="text-gray-500">尚未选择任何媒体文件</p>
<Button label="选择媒体" icon="pi pi-plus" @click="openMediaDialog" outlined />
<small v-if="errors.selectedMedia" class="p-error">{{ errors.selectedMedia }}</small>
<small v-if="errors.selectedMedia" class="text-red-500">{{ errors.selectedMedia }}</small>
</div>
<div v-else>
<div class="mb-4">