diff --git a/my-project-backend/src/main/java/com/example/controller/ForumController.java b/my-project-backend/src/main/java/com/example/controller/ForumController.java index d799956..85f46ae 100644 --- a/my-project-backend/src/main/java/com/example/controller/ForumController.java +++ b/my-project-backend/src/main/java/com/example/controller/ForumController.java @@ -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 addComment(@Valid @RequestBody AddCommentVO vo, + @RequestAttribute(Const.ATTR_USER_ID) int id) { + return utils.messageHandle(() -> topicService.createComment(vo, id)); + } } diff --git a/my-project-backend/src/main/java/com/example/entity/dto/TopicComment.java b/my-project-backend/src/main/java/com/example/entity/dto/TopicComment.java new file mode 100644 index 0000000..b19dc78 --- /dev/null +++ b/my-project-backend/src/main/java/com/example/entity/dto/TopicComment.java @@ -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; +} diff --git a/my-project-backend/src/main/java/com/example/entity/vo/request/AddCommentVO.java b/my-project-backend/src/main/java/com/example/entity/vo/request/AddCommentVO.java new file mode 100644 index 0000000..568521d --- /dev/null +++ b/my-project-backend/src/main/java/com/example/entity/vo/request/AddCommentVO.java @@ -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; +} diff --git a/my-project-backend/src/main/java/com/example/mapper/TopicCommentMapper.java b/my-project-backend/src/main/java/com/example/mapper/TopicCommentMapper.java new file mode 100644 index 0000000..d9bb76a --- /dev/null +++ b/my-project-backend/src/main/java/com/example/mapper/TopicCommentMapper.java @@ -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 { +} diff --git a/my-project-backend/src/main/java/com/example/service/TopicService.java b/my-project-backend/src/main/java/com/example/service/TopicService.java index 8861713..1107c45 100644 --- a/my-project-backend/src/main/java/com/example/service/TopicService.java +++ b/my-project-backend/src/main/java/com/example/service/TopicService.java @@ -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 { TopicDetailVO getTopic(int tid, int uid); void interact(Interact interact, boolean state); List listCollectTopic(int uid); + String createComment(AddCommentVO vo, int uid); } diff --git a/my-project-backend/src/main/java/com/example/service/impl/TopicServiceImpl.java b/my-project-backend/src/main/java/com/example/service/impl/TopicServiceImpl.java index baddf0b..968aeb7 100644 --- a/my-project-backend/src/main/java/com/example/service/impl/TopicServiceImpl.java +++ b/my-project-backend/src/main/java/com/example/service/impl/TopicServiceImpl.java @@ -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 implements @Resource AccountPrivacyMapper accountPrivacyMapper; + @Resource + TopicCommentMapper commentMapper; + @Resource FlowUtils flowUtils; @@ -152,6 +156,19 @@ public class TopicServiceImpl extends ServiceImpl 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)) diff --git a/my-project-backend/src/main/java/com/example/utils/Const.java b/my-project-backend/src/main/java/com/example/utils/Const.java index 76133a8..d7a065a 100644 --- a/my-project-backend/src/main/java/com/example/utils/Const.java +++ b/my-project-backend/src/main/java/com/example/utils/Const.java @@ -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:"; } diff --git a/my-project-frontend/src/assets/quill.css b/my-project-frontend/src/assets/quill.css new file mode 100644 index 0000000..89bb073 --- /dev/null +++ b/my-project-frontend/src/assets/quill.css @@ -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; +} diff --git a/my-project-frontend/src/components/TopicCommentEditor.vue b/my-project-frontend/src/components/TopicCommentEditor.vue new file mode 100644 index 0000000..6360a49 --- /dev/null +++ b/my-project-frontend/src/components/TopicCommentEditor.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/my-project-frontend/src/components/TopicEditor.vue b/my-project-frontend/src/components/TopicEditor.vue index 41ec637..bbb0c9e 100644 --- a/my-project-frontend/src/components/TopicEditor.vue +++ b/my-project-frontend/src/components/TopicEditor.vue @@ -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; -} diff --git a/my-project-frontend/src/main.js b/my-project-frontend/src/main.js index 97c993f..88e32c3 100644 --- a/my-project-frontend/src/main.js +++ b/my-project-frontend/src/main.js @@ -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' diff --git a/my-project-frontend/src/views/forum/Forum.vue b/my-project-frontend/src/views/forum/Forum.vue index 5e10a28..ace59e5 100644 --- a/my-project-frontend/src/views/forum/Forum.vue +++ b/my-project-frontend/src/views/forum/Forum.vue @@ -21,6 +21,6 @@ get('/api/forum/types', data => { - + diff --git a/my-project-frontend/src/views/forum/TopicDetail.vue b/my-project-frontend/src/views/forum/TopicDetail.vue index 3bfc9e7..5110a97 100644 --- a/my-project-frontend/src/views/forum/TopicDetail.vue +++ b/my-project-frontend/src/views/forum/TopicDetail.vue @@ -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) { + +
+
+ +
+ +