This commit is contained in:
李琦
2026-01-15 16:37:58 +08:00
parent 944d642d38
commit 782bcdd4d7
6 changed files with 1132 additions and 118 deletions

View File

@@ -1,95 +1,97 @@
<template>
<div class="post-form-container">
<h1 class="page-title">{{ isEditing ? '编辑文章' : '新建文章' }}</h1>
<div class="form-container">
<form @submit.prevent="handleSubmit" class="post-form">
<!-- Title Field -->
<div class="form-group">
<label for="title">文章标题</label>
<input
type="text"
id="title"
v-model="form.title"
placeholder="请输入文章标题"
required
<input
type="text"
id="title"
v-model="form.title"
placeholder="请输入文章标题"
required
/>
<div class="error-message" v-if="errors.title">
{{ errors.title }}
</div>
</div>
<!-- Category Field -->
<div class="form-group">
<label for="category">分类</label>
<input
type="text"
id="category"
v-model="form.category"
placeholder="请输入文章分类"
required
<input
type="text"
id="category"
v-model="form.category"
placeholder="请输入文章分类"
required
/>
<div class="error-message" v-if="errors.category">
{{ errors.category }}
</div>
</div>
<!-- Date Field -->
<div class="form-group">
<label for="date">发布日期</label>
<input
type="date"
id="date"
v-model="form.date"
required
<input
type="date"
id="date"
v-model="form.date"
required
/>
<div class="error-message" v-if="errors.date">
{{ errors.date }}
</div>
</div>
<!-- Excerpt Field -->
<div class="form-group">
<label for="excerpt">文章摘要</label>
<textarea
id="excerpt"
v-model="form.excerpt"
placeholder="请输入文章摘要"
rows="3"
<textarea
id="excerpt"
v-model="form.excerpt"
placeholder="请输入文章摘要"
rows="3"
></textarea>
<div class="error-message" v-if="errors.excerpt">
{{ errors.excerpt }}
</div>
</div>
<!-- Content Field -->
<!-- Content Field - 使用 Markdown 编辑器 -->
<div class="form-group">
<label for="content">文章内容</label>
<textarea
id="content"
v-model="form.content"
placeholder="请输入文章内容"
rows="10"
required
></textarea>
<label>文章内容</label>
<div class="editor-wrapper">
<MdEditor
v-model="form.content"
theme="dark"
:preview="false"
placeholder="请输入 Markdown 内容..."
class="custom-md-editor"
/>
</div>
<div class="error-message" v-if="errors.content">
{{ errors.content }}
</div>
</div>
<!-- Is Published Field -->
<div class="form-group">
<label for="isPublished">发布状态</label>
<CustomSelect
v-model="form.isPublished"
:options="publishStatusOptions"
placeholder="请选择发布状态"
v-model="form.isPublished"
:options="publishStatusOptions"
placeholder="请选择发布状态"
/>
<div class="error-message" v-if="errors.isPublished">
{{ errors.isPublished }}
</div>
</div>
<!-- Submit Buttons -->
<div class="form-actions">
<button type="button" class="cancel-btn" @click="handleCancel">
@@ -107,6 +109,10 @@
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
// 引入 md-editor-v3
import { MdEditor } from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import { useToast } from '../../composables/useToast'
import { createPost, updatePost, fetchPost } from '../../services/api'
import CustomSelect from '../../components/CustomSelect.vue'
@@ -140,33 +146,33 @@ const publishStatusOptions = [
const validateForm = (): boolean => {
// Reset errors
Object.keys(errors).forEach(key => delete errors[key])
let isValid = true
// Validate title
if (!form.title.trim()) {
errors.title = '文章标题不能为空'
isValid = false
}
// Validate category
if (!form.category.trim()) {
errors.category = '文章分类不能为空'
isValid = false
}
// Validate date
if (!form.date) {
errors.date = '发布日期不能为空'
isValid = false
}
// Validate content
if (!form.content.trim()) {
errors.content = '文章内容不能为空'
isValid = false
}
return isValid
}
@@ -175,9 +181,9 @@ const handleSubmit = async () => {
if (!validateForm()) {
return
}
isSubmitting.value = true
try {
if (isEditing.value) {
// Update existing post
@@ -188,7 +194,7 @@ const handleSubmit = async () => {
await createPost(form)
toast.success('文章创建成功')
}
// Redirect to posts list
router.push('/admin/posts')
} catch (error: any) {
@@ -211,7 +217,7 @@ onMounted(async () => {
try {
const postId = route.params.id as string
const post = await fetchPost(postId)
// Populate form with post data
form.title = post.title
form.category = post.category
@@ -350,19 +356,54 @@ onMounted(async () => {
cursor: not-allowed;
}
/* MdEditor Customization */
.editor-wrapper {
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 0.5rem;
overflow: hidden;
transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.editor-wrapper:focus-within {
border-color: #d4b383;
box-shadow: 0 0 0 3px rgba(212, 179, 131, 0.2);
}
:deep(.custom-md-editor) {
background-color: rgba(255, 255, 255, 0.05) !important;
--md-bk-color: transparent !important;
--md-color: white !important;
--md-border-color: transparent !important;
height: 500px;
}
:deep(.md-editor-toolbar-wrapper) {
background-color: rgba(0, 0, 0, 0.2) !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.1) !important;
}
:deep(.md-editor-content) {
background-color: transparent !important;
}
:deep(.md-editor-footer) {
background-color: rgba(0, 0, 0, 0.2) !important;
border-top: 1px solid rgba(255, 255, 255, 0.1) !important;
}
/* Responsive Design */
@media (max-width: 768px) {
.form-container {
padding: 1.5rem;
}
.form-actions {
flex-direction: column;
}
.cancel-btn,
.submit-btn {
width: 100%;
}
}
</style>
</style>