添加评论发表操作
This commit is contained in:
parent
863a1d4f0f
commit
47b71807e1
@ -2,6 +2,7 @@ package com.example.controller;
|
||||
|
||||
import com.example.entity.RestBean;
|
||||
import com.example.entity.dto.Interact;
|
||||
import com.example.entity.vo.request.AddCommentVO;
|
||||
import com.example.entity.vo.request.TopicCreateVO;
|
||||
import com.example.entity.vo.request.TopicUpdateVO;
|
||||
import com.example.entity.vo.response.*;
|
||||
@ -93,4 +94,10 @@ public class ForumController {
|
||||
topicService.updateTopic(id, vo);
|
||||
return RestBean.success();
|
||||
}
|
||||
|
||||
@PostMapping("/add-comment")
|
||||
public RestBean<String> addComment(@Valid @RequestBody AddCommentVO vo,
|
||||
@RequestAttribute(Const.ATTR_USER_ID) int id) {
|
||||
return utils.messageHandle(() -> topicService.createComment(vo, id));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package com.example.entity.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("db_topic_comments")
|
||||
public class TopicComment {
|
||||
@TableId(type = IdType.AUTO)
|
||||
Integer id;
|
||||
Integer tid;
|
||||
Integer uid;
|
||||
String content;
|
||||
Date time;
|
||||
Integer quote;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.example.entity.vo.request;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AddCommentVO {
|
||||
@Min(1)
|
||||
int tid;
|
||||
String content;
|
||||
@Min(-1)
|
||||
int quote;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.example.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.example.entity.dto.TopicComment;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface TopicCommentMapper extends BaseMapper<TopicComment> {
|
||||
}
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.example.entity.dto.Interact;
|
||||
import com.example.entity.dto.Topic;
|
||||
import com.example.entity.dto.TopicType;
|
||||
import com.example.entity.vo.request.AddCommentVO;
|
||||
import com.example.entity.vo.request.TopicCreateVO;
|
||||
import com.example.entity.vo.request.TopicUpdateVO;
|
||||
import com.example.entity.vo.response.TopicPreviewVO;
|
||||
@ -21,4 +22,5 @@ public interface TopicService extends IService<Topic> {
|
||||
TopicDetailVO getTopic(int tid, int uid);
|
||||
void interact(Interact interact, boolean state);
|
||||
List<TopicPreviewVO> listCollectTopic(int uid);
|
||||
String createComment(AddCommentVO vo, int uid);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.example.entity.dto.*;
|
||||
import com.example.entity.vo.request.AddCommentVO;
|
||||
import com.example.entity.vo.request.TopicCreateVO;
|
||||
import com.example.entity.vo.request.TopicUpdateVO;
|
||||
import com.example.entity.vo.response.TopicDetailVO;
|
||||
@ -41,6 +42,9 @@ public class TopicServiceImpl extends ServiceImpl<TopicMapper, Topic> implements
|
||||
@Resource
|
||||
AccountPrivacyMapper accountPrivacyMapper;
|
||||
|
||||
@Resource
|
||||
TopicCommentMapper commentMapper;
|
||||
|
||||
@Resource
|
||||
FlowUtils flowUtils;
|
||||
|
||||
@ -152,6 +156,19 @@ public class TopicServiceImpl extends ServiceImpl<TopicMapper, Topic> implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createComment(AddCommentVO vo, int uid) {
|
||||
String key = Const.FORUM_TOPIC_COMMENT_COUNTER + uid;
|
||||
if(!flowUtils.limitPeriodCounterCheck(key, 2, 60))
|
||||
return "发表评论频繁,请稍后再试!";
|
||||
TopicComment comment = new TopicComment();
|
||||
comment.setUid(uid);
|
||||
BeanUtils.copyProperties(vo, comment);
|
||||
comment.setTime(new Date());
|
||||
commentMapper.insert(comment);
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasInteract(int tid, int uid, String type){
|
||||
String key = tid + ":" + uid;
|
||||
if(template.opsForHash().hasKey(type, key))
|
||||
|
@ -26,5 +26,6 @@ public final class Const {
|
||||
public final static String FORUM_IMAGE_COUNTER = "image:upload:";
|
||||
public final static String FORUM_WEATHER_CACHE = "weather:cache:";
|
||||
public final static String FORUM_TOPIC_CREATE_COUNTER = "topic:create:";
|
||||
public final static String FORUM_TOPIC_COMMENT_COUNTER = "topic:comment:";
|
||||
public final static String FORUM_TOPIC_PREVIEW_CACHE = "topic:preview:";
|
||||
}
|
||||
|
15
my-project-frontend/src/assets/quill.css
Normal file
15
my-project-frontend/src/assets/quill.css
Normal file
@ -0,0 +1,15 @@
|
||||
.ql-toolbar {
|
||||
border-radius: 5px 5px 0 0;
|
||||
border-color: var(--el-border-color) !important;
|
||||
}
|
||||
.ql-container{
|
||||
border-radius: 0 0 5px 5px;
|
||||
border-color: var(--el-border-color) !important;
|
||||
}
|
||||
.ql-editor.ql-blank::before{
|
||||
color: grey !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
.ql-editor {
|
||||
font-size: 14px;
|
||||
}
|
61
my-project-frontend/src/components/TopicCommentEditor.vue
Normal file
61
my-project-frontend/src/components/TopicCommentEditor.vue
Normal file
@ -0,0 +1,61 @@
|
||||
<script setup>
|
||||
import {QuillEditor} from "@vueup/vue-quill";
|
||||
import '@vueup/vue-quill/dist/vue-quill.snow.css';
|
||||
import {post} from "@/net";
|
||||
import {reactive, ref} from "vue";
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
quote: Number,
|
||||
show: Boolean,
|
||||
tid: String
|
||||
})
|
||||
const emit = defineEmits(['close'])
|
||||
|
||||
const content = ref()
|
||||
|
||||
function submitComment() {
|
||||
post('/api/forum/add-comment', {
|
||||
tid: props.tid,
|
||||
content: JSON.stringify(content.value),
|
||||
quote: props.quote
|
||||
}, () => {
|
||||
ElMessage.success('评论成功')
|
||||
emit('close')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer :model-value="show"
|
||||
title="发表回复"
|
||||
:size="270" direction="btt"
|
||||
@close="emit('close')"
|
||||
:show-close="false">
|
||||
<div style="padding: 10px;width: 100%">
|
||||
<div>
|
||||
<quill-editor style="height: 100px" v-model:content="content"
|
||||
placeholder="请发表友善的评论,不要使用脏话骂人,都是大学生素质高一点"/>
|
||||
</div>
|
||||
<div style="margin-top: 10px;text-align: right">
|
||||
<el-button @click="submitComment" type="success" plain>发表评论</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.el-drawer) {
|
||||
width: 800px;
|
||||
margin: 20px auto;
|
||||
border-radius: 10px;
|
||||
}
|
||||
:deep(.el-drawer__header) {
|
||||
margin: 0;
|
||||
}
|
||||
:deep(.el-drawer__body) {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
@ -196,19 +196,4 @@ const editorOption = {
|
||||
:deep(.el-drawer__header) {
|
||||
margin: 0;
|
||||
}
|
||||
:deep(.ql-toolbar) {
|
||||
border-radius: 5px 5px 0 0;
|
||||
border-color: var(--el-border-color);
|
||||
}
|
||||
:deep(.ql-container){
|
||||
border-radius: 0 0 5px 5px;
|
||||
border-color: var(--el-border-color);
|
||||
}
|
||||
:deep(.ql-editor.ql-blank::before){
|
||||
color: grey;
|
||||
font-style: normal;
|
||||
}
|
||||
:deep(.ql-editor) {
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
@ -5,6 +5,7 @@ import axios from "axios";
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||
import '@/assets/quill.css'
|
||||
|
||||
axios.defaults.baseURL = 'http://localhost:8080'
|
||||
|
||||
|
@ -21,6 +21,6 @@ get('/api/forum/types', data => {
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
<el-backtop target=".main-content-page .el-scrollbar__wrap" :right="20" :bottom="20"/>
|
||||
<el-backtop target=".main-content-page .el-scrollbar__wrap" :right="20" :bottom="70"/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -3,7 +3,7 @@ import {useRoute} from "vue-router";
|
||||
import {get, post} from "@/net";
|
||||
import {computed, reactive, ref} from "vue";
|
||||
import axios from "axios";
|
||||
import {ArrowLeft, CircleCheck, EditPen, Female, Male, Star} from "@element-plus/icons-vue";
|
||||
import {ArrowLeft, CircleCheck, EditPen, Female, Male, Plus, Star} from "@element-plus/icons-vue";
|
||||
import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html';
|
||||
import {useStore} from "@/store";
|
||||
import Card from "@/components/Card.vue";
|
||||
@ -12,6 +12,7 @@ import InteractButton from "@/components/InteractButton.vue";
|
||||
import {ElMessage} from "element-plus";
|
||||
import TopicTag from "@/components/TopicTag.vue";
|
||||
import TopicEditor from "@/components/TopicEditor.vue";
|
||||
import TopicCommentEditor from "@/components/TopicCommentEditor.vue";
|
||||
|
||||
const route = useRoute()
|
||||
const store = useStore()
|
||||
@ -25,6 +26,11 @@ const topic = reactive({
|
||||
comments: []
|
||||
})
|
||||
const edit = ref(false)
|
||||
const comment = reactive({
|
||||
show: false,
|
||||
text: '',
|
||||
quote: -1
|
||||
})
|
||||
|
||||
function init() {
|
||||
get(`/api/forum/topic?tid=${tid}`, data => {
|
||||
@ -124,15 +130,43 @@ function updateTopic(editor) {
|
||||
</interact-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topic-main">
|
||||
|
||||
</div>
|
||||
<topic-editor :show="edit" @close="edit = false" v-if="topic.data"
|
||||
:default-title="topic.data.title" :default-text="topic.data.content"
|
||||
:default-type="topic.data.type" submit-button="更新帖子内容"
|
||||
:submit="updateTopic"/>
|
||||
<topic-comment-editor :show="comment.show" @close="comment.show = false"
|
||||
:quote="comment.quote" :tid="tid"/>
|
||||
<div class="add-comment" @click="comment.show = true">
|
||||
<el-icon><Plus /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.add-comment {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
line-height: 45px;
|
||||
font-size: 18px;
|
||||
color: var(--el-color-primary);
|
||||
text-align: center;
|
||||
border-radius: 20px;
|
||||
background: var(--el-bg-color-overlay);
|
||||
box-shadow: var(--el-box-shadow-lighter);
|
||||
|
||||
&:hover {
|
||||
background: var(--el-border-color-extra-light);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.topic-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
Loading…
x
Reference in New Issue
Block a user