【在线OJ】发帖功能前后段代码实现
一、页面布局
二、前端代码
<template>
<div id="app">
<div style="height: 100vh">
<div style="display: flex" >
<el-input style="width: 95%" v-model="title" placeholder="输入标题"></el-input>
<el-button style="width: 5%; margin-left: 2px" type="primary" size="small" @click="submit">发布</el-button>
</div>
<quill-editor style="height: 100vh" v-model="content"></quill-editor>
<el-drawer
title="请选择类型"
:before-close="handleClose"
:visible.sync="dialog"
direction="rtl"
custom-class="demo-drawer"
ref="drawer"
>
<div class="demo-drawer__content">
<el-form :model="form">
<el-form-item label="类型" :label-width="formLabelWidth">
<el-select v-model="type" placeholder="请选择文章类型">
<el-option v-for="item in types" :key="item.id" :label="item.type" :value="item.id" @click="onchange(item.id)"></el-option>
</el-select>
</el-form-item>
<el-upload
class="avatar-uploader"
action="http://127.0.0.1:8388/forum/article/public/postPhoto"
list-type="picture-card"
:show-file-list="false"
:on-success="success"
:headers="headers"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form>
<div class="demo-drawer__footer">
<el-button @click="cancelForm">{{'取 消'}}</el-button>
<el-button type="primary" @click="cancelForm">{{ '确 定' }}</el-button>
</div>
</div>
</el-drawer>
</div>
</div>
</template>
<script>
import axios from "axios";
const options = {
data: function () {
return {
imageUrl: '',
headers: {
"token": localStorage.getItem("token")
},
types: [],
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
formLabelWidth: '80px',
timer: null,
dialog: false,
title: "",
content: "",
type: "",
photo: "",
loading: false,
};
},
async mounted() {
await this.getTypes()
// 获取查询字符串
let id = this.$route.query.id
if (id === '' || id === undefined) {
console.log(id)
} else {
this.$message({
message: '查询数据',
type: 'success'
});
this.title = '这是一篇关于……的帖子'
this.content= '需要查询数据库进行编写'
const resp = await axios.get("http://localhost:8388/forum/article/public/queryById", {
params: {
"id": id,
}
})
if (resp.data.code === 200) {
this.title = resp.data.data.title
this.content = resp.data.data.content
}
}
},
methods: {
onchange(id) {
this.type = id
},
success: function(response, file, fileList) {
console.log(file)
console.log(fileList)
const data = response; // 从服务器返回的数据中获取上传成功后的头像地址
console.log(data)
if (data.code === 200) {
console.log(data)
this.photo = data.data
}
console.log(response)
},
beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
return false
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
return false
}
return true
},
cancelForm() {
this.dialog = false;
this.loading = false;
},
async getTypes() {
this.currentType = 0
const resp = await axios.get("http://localhost:8388/forum/article/public/showTypes");
if (resp.data.code === 200) {
this.types = resp.data.data
}
// this.types.unshift({id : 0, type: "全部"})
},
handleClose() {
this.dialog = false
},
async submit() {
console.log(this.type)
console.log(this.photo)
if (!this.type || !this.photo) {
this.dialog = true;
return;
}
if (this.$route.query.id === undefined) {
console.log('提交的内容:', this.content)
const resp = await axios.post("http://localhost:8388/forum/article/public/PostArticle", {
title: this.title,
content: this.content,
type: this.type,
photo: this.photo
}, {
headers: {
token: localStorage.getItem("token")
}
})
if (resp.data.code === 200) {
this.$message({
message: '发布成功',
type: 'success'
});
await this.$router.push({
path: '/forum',
})
}
} else {
console.log('提交的内容:', this.content)
const resp = await axios.post("http://localhost:8388/forum/article/public/updateArticle", {
title: this.title,
content: this.content,
type: this.type,
id: this.$route.query.id
}, {
headers: {
token: localStorage.getItem("token")
}
})
if (resp.data.code === 200) {
this.$message({
message: '修改成功',
type: 'success'
});
await this.$router.push({
path: '/article',
query: {
id: this.$route.query.id
}
})
}
}
}
},
computed: {
}
};
export default options;
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
三、后端代码