<template>
|
|
<div class="create-work-container">
|
|
<div class="create-work-content">
|
|
<h2 class="page-title">创建新作品</h2>
|
|
|
|
<div class="form-container">
|
|
<el-form :model="workForm" :rules="rules" ref="workFormRef" label-position="top">
|
|
<el-form-item label="作品名称" prop="title">
|
|
<el-input v-model="workForm.title" placeholder="请输入作品名称"></el-input>
|
|
</el-form-item>
|
|
|
|
<el-form-item label="作品分类" prop="category">
|
|
<el-select v-model="workForm.category" placeholder="请选择分类">
|
|
<el-option v-for="item in categories" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-form-item label="作品标签" prop="tags">
|
|
<el-select
|
|
v-model="workForm.tags"
|
|
multiple
|
|
placeholder="请选择标签(最多选择3个)"
|
|
:multiple-limit="3"
|
|
>
|
|
<el-option v-for="item in tags" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-form-item label="简介" prop="description">
|
|
<el-input
|
|
v-model="workForm.description"
|
|
type="textarea"
|
|
:rows="5"
|
|
placeholder="请输入作品简介"
|
|
maxlength="500"
|
|
show-word-limit
|
|
></el-input>
|
|
</el-form-item>
|
|
|
|
<el-form-item label="封面图片">
|
|
<el-upload
|
|
class="cover-uploader"
|
|
action="#"
|
|
:http-request="uploadCover"
|
|
:show-file-list="false"
|
|
:before-upload="beforeUpload"
|
|
>
|
|
<img v-if="workForm.cover" :src="workForm.cover" class="cover-image" />
|
|
<div v-else class="cover-placeholder">
|
|
<el-icon><Plus /></el-icon>
|
|
<div class="upload-text">点击上传封面</div>
|
|
</div>
|
|
</el-upload>
|
|
<div class="upload-tip">建议尺寸:300x400像素,JPG/PNG格式</div>
|
|
</el-form-item>
|
|
|
|
<div class="form-actions">
|
|
<el-button @click="goBack">取消</el-button>
|
|
<el-button type="primary" @click="submitForm" :loading="loading">创建作品</el-button>
|
|
</div>
|
|
</el-form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { defineComponent, ref, reactive } from 'vue';
|
|
import { useRouter } from 'vue-router';
|
|
import { ElMessage } from 'element-plus';
|
|
import { Plus } from '@element-plus/icons-vue';
|
|
|
|
export default defineComponent({
|
|
name: 'CreateWork',
|
|
components: {
|
|
Plus
|
|
},
|
|
setup() {
|
|
const router = useRouter();
|
|
const workFormRef = ref(null);
|
|
const loading = ref(false);
|
|
|
|
// 表单数据
|
|
const workForm = reactive({
|
|
title: '',
|
|
category: '',
|
|
tags: [],
|
|
description: '',
|
|
cover: ''
|
|
});
|
|
|
|
// 表单验证规则
|
|
const rules = {
|
|
title: [
|
|
{ required: true, message: '请输入作品名称', trigger: 'blur' },
|
|
{ min: 2, max: 30, message: '长度应为2-30个字符', trigger: 'blur' }
|
|
],
|
|
category: [
|
|
{ required: true, message: '请选择作品分类', trigger: 'change' }
|
|
],
|
|
description: [
|
|
{ required: true, message: '请输入作品简介', trigger: 'blur' },
|
|
{ min: 10, max: 500, message: '简介长度应为10-500个字符', trigger: 'blur' }
|
|
]
|
|
};
|
|
|
|
// 分类和标签数据,实际应用中应该从API获取
|
|
const categories = ref([
|
|
{ id: 1, name: '玄幻' },
|
|
{ id: 2, name: '奇幻' },
|
|
{ id: 3, name: '武侠' },
|
|
{ id: 4, name: '仙侠' },
|
|
{ id: 5, name: '都市' },
|
|
{ id: 6, name: '历史' },
|
|
{ id: 7, name: '军事' },
|
|
{ id: 8, name: '科幻' }
|
|
]);
|
|
|
|
const tags = ref([
|
|
{ id: 1, name: '热血' },
|
|
{ id: 2, name: '爽文' },
|
|
{ id: 3, name: '冒险' },
|
|
{ id: 4, name: '复仇' },
|
|
{ id: 5, name: '种田' },
|
|
{ id: 6, name: '经商' },
|
|
{ id: 7, name: '争霸' },
|
|
{ id: 8, name: '升级' },
|
|
{ id: 9, name: '穿越' },
|
|
{ id: 10, name: '重生' }
|
|
]);
|
|
|
|
// 上传前校验
|
|
const beforeUpload = (file) => {
|
|
const isImage = file.type === 'image/jpeg' || file.type === 'image/png';
|
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
|
|
|
if (!isImage) {
|
|
ElMessage.error('封面图片只能是JPG或PNG格式!');
|
|
return false;
|
|
}
|
|
if (!isLt2M) {
|
|
ElMessage.error('封面图片大小不能超过2MB!');
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
// 上传封面
|
|
const uploadCover = (options) => {
|
|
const { file } = options;
|
|
// 实际应用中应该上传到服务器,这里模拟上传成功
|
|
const reader = new FileReader();
|
|
reader.readAsDataURL(file);
|
|
reader.onload = (e) => {
|
|
workForm.cover = e.target.result;
|
|
};
|
|
};
|
|
|
|
// 提交表单
|
|
const submitForm = () => {
|
|
workFormRef.value.validate(async (valid) => {
|
|
if (valid) {
|
|
try {
|
|
loading.value = true;
|
|
// 模拟API调用,实际项目中应调用真实的后端API
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
|
ElMessage.success('作品创建成功!');
|
|
router.push({ name: 'authorCenter' });
|
|
} catch (error) {
|
|
ElMessage.error('创建失败,请稍后重试');
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
} else {
|
|
ElMessage.warning('请正确填写表单信息');
|
|
return false;
|
|
}
|
|
});
|
|
};
|
|
|
|
// 返回上一页
|
|
const goBack = () => {
|
|
router.back();
|
|
};
|
|
|
|
return {
|
|
workFormRef,
|
|
workForm,
|
|
rules,
|
|
categories,
|
|
tags,
|
|
loading,
|
|
beforeUpload,
|
|
uploadCover,
|
|
submitForm,
|
|
goBack
|
|
};
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.create-work-container {
|
|
background-color: #f5f5f9;
|
|
min-height: calc(100vh - 60px);
|
|
padding: 30px 0;
|
|
|
|
.create-work-content {
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 30px;
|
|
background-color: #fff;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
|
|
|
|
.page-title {
|
|
font-size: 24px;
|
|
color: #333;
|
|
margin: 0 0 30px;
|
|
padding-bottom: 15px;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.form-container {
|
|
:deep(.el-form-item__label) {
|
|
font-weight: 500;
|
|
color: #333;
|
|
}
|
|
|
|
:deep(.el-input__wrapper) {
|
|
padding: 0 15px;
|
|
height: 44px;
|
|
}
|
|
|
|
.cover-uploader {
|
|
.cover-image {
|
|
width: 150px;
|
|
height: 200px;
|
|
object-fit: cover;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.cover-placeholder {
|
|
width: 150px;
|
|
height: 200px;
|
|
background-color: #f7f9fc;
|
|
border: 1px dashed #d9d9d9;
|
|
border-radius: 4px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
border-color: #0A2463;
|
|
color: #0A2463;
|
|
}
|
|
|
|
.el-icon {
|
|
font-size: 28px;
|
|
color: #8c939d;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.upload-text {
|
|
font-size: 14px;
|
|
color: #8c939d;
|
|
}
|
|
}
|
|
}
|
|
|
|
.upload-tip {
|
|
font-size: 12px;
|
|
color: #aaa;
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.form-actions {
|
|
margin-top: 40px;
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 20px;
|
|
|
|
.el-button {
|
|
width: 120px;
|
|
}
|
|
|
|
.el-button--primary {
|
|
background-color: #0A2463;
|
|
border-color: #0A2463;
|
|
|
|
&:hover, &:focus {
|
|
background-color: #1a3473;
|
|
border-color: #1a3473;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|