完成帖子编辑操作
This commit is contained in:
parent
9777bc26cc
commit
863a1d4f0f
@ -3,6 +3,7 @@ package com.example.controller;
|
||||
import com.example.entity.RestBean;
|
||||
import com.example.entity.dto.Interact;
|
||||
import com.example.entity.vo.request.TopicCreateVO;
|
||||
import com.example.entity.vo.request.TopicUpdateVO;
|
||||
import com.example.entity.vo.response.*;
|
||||
import com.example.service.TopicService;
|
||||
import com.example.service.WeatherService;
|
||||
@ -67,8 +68,9 @@ public class ForumController {
|
||||
}
|
||||
|
||||
@GetMapping("/topic")
|
||||
public RestBean<TopicDetailVO> topic(@RequestParam @Min(0) int tid){
|
||||
return RestBean.success(topicService.getTopic(tid));
|
||||
public RestBean<TopicDetailVO> topic(@RequestParam @Min(0) int tid,
|
||||
@RequestAttribute(Const.ATTR_USER_ID) int id){
|
||||
return RestBean.success(topicService.getTopic(tid, id));
|
||||
}
|
||||
|
||||
@GetMapping("/interact")
|
||||
@ -84,4 +86,11 @@ public class ForumController {
|
||||
public RestBean<List<TopicPreviewVO>> collects(@RequestAttribute(Const.ATTR_USER_ID) int id){
|
||||
return RestBean.success(topicService.listCollectTopic(id));
|
||||
}
|
||||
|
||||
@PostMapping("/update-topic")
|
||||
public RestBean<Void> updateTopic(@Valid @RequestBody TopicUpdateVO vo,
|
||||
@RequestAttribute(Const.ATTR_USER_ID) int id) {
|
||||
topicService.updateTopic(id, vo);
|
||||
return RestBean.success();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
package com.example.entity.vo.request;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
@Data
|
||||
public class TopicUpdateVO {
|
||||
@Min(0)
|
||||
int id;
|
||||
@Min(1)
|
||||
@Max(5)
|
||||
int type;
|
||||
@Length(max = 30)
|
||||
String title;
|
||||
JSONObject content;
|
||||
}
|
@ -6,6 +6,7 @@ import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class AccountVO {
|
||||
int id;
|
||||
String username;
|
||||
String email;
|
||||
String role;
|
||||
|
@ -5,6 +5,7 @@ import com.example.entity.dto.Interact;
|
||||
import com.example.entity.dto.Topic;
|
||||
import com.example.entity.dto.TopicType;
|
||||
import com.example.entity.vo.request.TopicCreateVO;
|
||||
import com.example.entity.vo.request.TopicUpdateVO;
|
||||
import com.example.entity.vo.response.TopicPreviewVO;
|
||||
import com.example.entity.vo.response.TopicTopVO;
|
||||
import com.example.entity.vo.response.TopicDetailVO;
|
||||
@ -14,9 +15,10 @@ import java.util.List;
|
||||
public interface TopicService extends IService<Topic> {
|
||||
List<TopicType> listType();
|
||||
String createTopic(int uid, TopicCreateVO vo);
|
||||
void updateTopic(int uid, TopicUpdateVO vo);
|
||||
List<TopicPreviewVO> listTopicByPage(int pageNumber, int type);
|
||||
List<TopicTopVO> topTopics();
|
||||
TopicDetailVO getTopic(int tid);
|
||||
TopicDetailVO getTopic(int tid, int uid);
|
||||
void interact(Interact interact, boolean state);
|
||||
List<TopicPreviewVO> listCollectTopic(int uid);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ 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.TopicCreateVO;
|
||||
import com.example.entity.vo.request.TopicUpdateVO;
|
||||
import com.example.entity.vo.response.TopicDetailVO;
|
||||
import com.example.entity.vo.response.TopicPreviewVO;
|
||||
import com.example.entity.vo.response.TopicTopVO;
|
||||
@ -54,6 +55,17 @@ public class TopicServiceImpl extends ServiceImpl<TopicMapper, Topic> implements
|
||||
return typeMapper.selectList(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTopic(int uid, TopicUpdateVO vo) {
|
||||
baseMapper.update(null, Wrappers.<Topic>update()
|
||||
.eq("uid", uid)
|
||||
.eq("id", vo.getId())
|
||||
.set("title", vo.getTitle())
|
||||
.set("content", vo.getContent().toString())
|
||||
.set("type", vo.getType())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createTopic(int uid, TopicCreateVO vo) {
|
||||
if(!this.textLimitCheck(vo.getContent()))
|
||||
@ -116,13 +128,13 @@ public class TopicServiceImpl extends ServiceImpl<TopicMapper, Topic> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public TopicDetailVO getTopic(int tid) {
|
||||
public TopicDetailVO getTopic(int tid, int uid) {
|
||||
TopicDetailVO vo = new TopicDetailVO();
|
||||
Topic topic = baseMapper.selectById(tid);
|
||||
BeanUtils.copyProperties(topic, vo);
|
||||
TopicDetailVO.Interact interact = new TopicDetailVO.Interact(
|
||||
hasInteract(tid, topic.getUid(), "like"),
|
||||
hasInteract(tid, topic.getUid(), "collect")
|
||||
hasInteract(tid, uid, "like"),
|
||||
hasInteract(tid, uid, "collect")
|
||||
);
|
||||
vo.setInteract(interact);
|
||||
TopicDetailVO.User user = new TopicDetailVO.User();
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import {Document} from "@element-plus/icons-vue";
|
||||
import {QuillEditor, Quill} from "@vueup/vue-quill";
|
||||
import {QuillEditor, Quill, Delta} from "@vueup/vue-quill";
|
||||
import {computed, reactive, ref} from "vue";
|
||||
import '@vueup/vue-quill/dist/vue-quill.snow.css';
|
||||
import {accessHeader, post} from "@/net";
|
||||
@ -10,9 +10,39 @@ import ImageResize from "quill-image-resize-vue";
|
||||
import { ImageExtend, QuillWatch } from "quill-image-super-solution-module";
|
||||
import {useStore} from "@/store";
|
||||
|
||||
defineProps({ show: Boolean })
|
||||
const props = defineProps({
|
||||
show: Boolean,
|
||||
defaultTitle: {
|
||||
default: '',
|
||||
type: String
|
||||
},
|
||||
defaultText: {
|
||||
default: '',
|
||||
type: String
|
||||
},
|
||||
defaultType: {
|
||||
default: 1,
|
||||
type: Number
|
||||
},
|
||||
submitButton: {
|
||||
default: '立即发布',
|
||||
type: String
|
||||
},
|
||||
submit: {
|
||||
default: (editor, success) => {
|
||||
post('/api/forum/create-topic', {
|
||||
type: editor.type,
|
||||
title: editor.title,
|
||||
content: editor.text
|
||||
}, () => {
|
||||
ElMessage.success("帖子发表成功!")
|
||||
success()
|
||||
})
|
||||
},
|
||||
type: Function
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['close', 'created'])
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const refEditor = ref()
|
||||
@ -24,9 +54,12 @@ const editor = reactive({
|
||||
})
|
||||
|
||||
function initEditor() {
|
||||
if(props.defaultText)
|
||||
editor.text = new Delta(JSON.parse(props.defaultText))
|
||||
else
|
||||
refEditor.value.setContents('', 'user')
|
||||
editor.title = ''
|
||||
editor.type = 1
|
||||
editor.title = props.defaultTitle
|
||||
editor.type = props.defaultType
|
||||
}
|
||||
|
||||
function submitTopic(){
|
||||
@ -43,14 +76,7 @@ function submitTopic(){
|
||||
ElMessage.warning('请选择一个合适的帖子类型!')
|
||||
return
|
||||
}
|
||||
post('/api/forum/create-topic', {
|
||||
type: editor.type,
|
||||
title: editor.title,
|
||||
content: editor.text
|
||||
}, () => {
|
||||
ElMessage.success("帖子发表成功!")
|
||||
emit('created')
|
||||
})
|
||||
props.submit(editor, () => emit('created'))
|
||||
}
|
||||
|
||||
function deltaToText(delta) {
|
||||
@ -154,7 +180,7 @@ const editorOption = {
|
||||
当前字数: {{ contentLength }}(最大支持20000字)
|
||||
</div>
|
||||
<div>
|
||||
<el-button @click="submitTopic" type="success" plain>立即发布</el-button>
|
||||
<el-button @click="submitTopic" type="success" plain>{{submitButton}}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
@ -5,6 +5,7 @@ export const useStore = defineStore('general', {
|
||||
state: () => {
|
||||
return {
|
||||
user: {
|
||||
id: -1,
|
||||
username: '',
|
||||
email: '',
|
||||
role: '',
|
||||
|
@ -1,9 +1,9 @@
|
||||
<script setup>
|
||||
import {useRoute} from "vue-router";
|
||||
import {get} from "@/net";
|
||||
import {computed, reactive} from "vue";
|
||||
import {get, post} from "@/net";
|
||||
import {computed, reactive, ref} from "vue";
|
||||
import axios from "axios";
|
||||
import {ArrowLeft, CircleCheck, Female, Male, Star} from "@element-plus/icons-vue";
|
||||
import {ArrowLeft, CircleCheck, EditPen, Female, Male, Star} from "@element-plus/icons-vue";
|
||||
import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html';
|
||||
import {useStore} from "@/store";
|
||||
import Card from "@/components/Card.vue";
|
||||
@ -11,6 +11,7 @@ import router from "@/router";
|
||||
import InteractButton from "@/components/InteractButton.vue";
|
||||
import {ElMessage} from "element-plus";
|
||||
import TopicTag from "@/components/TopicTag.vue";
|
||||
import TopicEditor from "@/components/TopicEditor.vue";
|
||||
|
||||
const route = useRoute()
|
||||
const store = useStore()
|
||||
@ -23,12 +24,16 @@ const topic = reactive({
|
||||
collect: false,
|
||||
comments: []
|
||||
})
|
||||
const edit = ref(false)
|
||||
|
||||
get(`/api/forum/topic?tid=${tid}`, data => {
|
||||
function init() {
|
||||
get(`/api/forum/topic?tid=${tid}`, data => {
|
||||
topic.data = data
|
||||
topic.like = data.interact.like
|
||||
topic.collect = data.interact.collect
|
||||
})
|
||||
})
|
||||
}
|
||||
init()
|
||||
|
||||
const content = computed(() => {
|
||||
const ops = JSON.parse(topic.data.content).ops
|
||||
@ -45,6 +50,19 @@ function interact(type, message) {
|
||||
ElMessage.success(`已取消${message}!`)
|
||||
})
|
||||
}
|
||||
|
||||
function updateTopic(editor) {
|
||||
post('/api/forum/update-topic', {
|
||||
id: tid,
|
||||
type: editor.type,
|
||||
title: editor.title,
|
||||
content: editor.text
|
||||
}, () => {
|
||||
ElMessage.success("帖子内容更新成功!")
|
||||
edit.value = false
|
||||
init()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -91,6 +109,10 @@ function interact(type, message) {
|
||||
<div>发帖时间: {{new Date(topic.data.time).toLocaleString()}}</div>
|
||||
</div>
|
||||
<div style="text-align: right;margin-top: 30px">
|
||||
<interact-button name="编辑帖子" color="dodgerblue" style="margin-right: 20px"
|
||||
:check="false" @check="edit = true" v-if="store.user.id === topic.data.user.uid">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
</interact-button>
|
||||
<interact-button name="点个赞吧" check-name="已点赞" color="pink"
|
||||
:check="topic.like" @check="interact('like', '点赞')">
|
||||
<el-icon><CircleCheck /></el-icon>
|
||||
@ -103,6 +125,10 @@ function interact(type, message) {
|
||||
</div>
|
||||
</div>
|
||||
</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"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user