Files
fe-student/src/views/discuss/DiscussPage.vue
2023-03-24 14:25:19 +08:00

628 lines
16 KiB
Vue

<template>
<div style=" background: #0078fc;height: 150px;width: 100%;position: absolute;top: 0;z-index:-9999;"></div>
<div class="surveydetail" style="padding: 30px">
<!-- 面包屑导航 -->
<div
style="display: flex; align-items: center; justify-content: space-between"
>
<div class="crumb">
<div>{{ pName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div>{{ sName }}</div>
<div style="margin-left: 6px; margin-right: 6px">/</div>
<div style="font-weight: 700; font-size: 16px">讨论详情</div>
</div>
<div class="preNext">
<span @click="prevPage" v-if="hasPrev">
<button class="btn btn01"></button>
<span class="content" style="margin-left: 6px">上一个</span>
</span>
<span @click="nextPage" v-if="hasNext">
<span class="content" style="margin-left: 31px">下一个</span>
<button class="btn btn02" style="margin-left: 6px"></button>
</span>
</div>
<div class="return">
<div style="display: flex" @click="returnclick">
<el-button style="color:#0073FB"> <img class="img2" style="margin-right:11px;cursor: pointer;" src="../../assets/image/return.png" />返回</el-button>
</div>
</div>
</div>
<!-- 面包屑导航 -->
<!-- 标题 -->
<div class="title">讨论{{ state.info.discussDtoList[0].discussName }}</div>
<!-- 标题 -->
<!-- 详细内容 -->
<div class="bascinfo clearfix">
<!-- 中间部分 -->
<div class="middletitle">
<div class="title">
{{ state.info.discussDtoList[0].discussExplain }}
</div>
<button class="btn" @click="showPostModal">发表帖子</button>
</div>
<div>
<div class="line clearfix">
<div class="linetitle">{{ state.info.discussDtoList[0].discussName }}</div>
<div class="radi"></div>
<div class="intime">进行中</div>
</div>
<div class="allbtn">
<button :class="`btnone ${state.searchType == 1 ? 'active' : ''}`" @click="nowPost(state.info.discussDtoList[0].id)">
最新
</button>
<button
:class="`btnone ${state.searchType == 2 ? 'active' : ''}`"
style="margin-left: 20px" @click="hotPost(state.info.discussDtoList[0].id)">
最热
</button>
</div>
<div
class="discusslist"
v-for="(d, j) in state?.postList"
:key="j">
<div class="itemtitle" @click="comment(d)">{{ d.title }}</div>
<div class="itemdiscuss" @click="comment(d)" :v-html="d.content"></div>
<div class="allstar clearfix">
<div @click="comment(d)" style="display: flex; cursor: pointer">
<span class="iconfont icon-pinglun" style="color: #b3bdc4"></span>
<div class="count">{{ d.commentNum || 0 }}</div>
</div>
<div @click="like(d)" style="display: flex; cursor: pointer">
<span
class="iconfont icon-dianzan"
:style="{
color: d.praised ? '#2478ff' : '#b3bdc4',
marginLeft: '19px',
}"
></span>
<div class="count" :style="{color:d.praised ? '#2478ff' : '#b3bdc4'}">{{ d.praiseNum || 0 }}</div>
</div>
<div @click="collection(d)" style="display: flex; cursor: pointer">
<span
class="iconfont icon-shoucang"
:style="{
color: d.collected ? '#2478ff' : '#b3bdc4',
marginLeft: '19px',
}"
></span>
<div class="count" :style="{color:d.collected ? '#2478ff' : '#b3bdc4'}">{{ d.collectionNum || 0 }}</div>
</div>
</div>
<div class="thinline"></div>
</div>
<div style="display:flex;justify-content:center;align-items:center;margin-top:36px;margin-bottom:36px;">
<!-- 分页 -->
<el-pagination
v-model:current-page="state.currentPage"
:page-size="state.pageSize"
:small="small"
layout="prev, pager, next, jumper"
:total="state.total"
@current-change="handleCurrentChange"
/>
</div>
</div>
</div>
<!-- 详细内容 -->
<!-- 富文本 -->
<el-dialog title="" top="" v-model="dialogVisible" :show-close="false" :loading="loading"
style="display:flex;justify-content:center;align-items:center;flex-direction: column;"
width="80%">
<div style="width:100%;margin-bottom: 12px;">
<el-input v-model="titleName" placeholder="请输入标题" />
</div>
<div style="border: 1px solid #ccc">
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig"
:mode="mode" />
<Editor style="height: 450px; overflow-y: hidden" v-model="valueHtml" :defaultConfig="editorConfig"
:mode="mode" @onCreated="handleCreated" />
</div>
<div style="width:100%;height:80px;display:flex;justify-content:center;align-items:center;margin-top:20px;">
<button
class="submitbtn btn01"
style="margin-right:40px;"
@click="cancelPost">
取消
</button>
<button
class="submitbtn btn01"
@click="postAdd">
发布
</button>
</div>
</el-dialog>
<!-- 富文本 -->
</div>
</template>
<script setup>
import { request, useRequest } from "@/api/request";
import {
COMMENT_COLLECTION,
COMMENT_PRAISE,
DISCUSS_LIST,
QueryDiscussSubmitDetailByDiscussId,
FILE_UPLOAD,
PostAdd,
PostDelete,
PostUpdate,
PostList,
PostPraise,
PostCollection,
} from "@/api/api";
import "@wangeditor/editor/dist/css/style.css";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { reactive, ref, toRefs, shallowRef, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import store from "@/store";
import { ElMessage } from "element-plus";
import { fileUp } from "../../api/request";
import {useTaskPage} from "@/api/useCommon";
import {ElLoading} from "element-plus";
const userInfo = computed(() => store.state.userInfo);
const router = useRouter();
const returnclick = () => {
router.back();
};
const {
query: { id, type, pName, sName },
} = useRoute();
const {nextPage,prevPage,hasPrev, hasNext} = useTaskPage()
const dialogVisible = ref(false);
const titleName = ref("");
const loading = ref(false);
const state = reactive({
activeName: "first",
info:{},
pageNo:1,
pageSize:10,
searchType:1,
postList: [], //帖子列表
total:0, // 帖子总条数
currentPage: 1,
content: 1
});
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
// 内容 HTML
const valueHtml = ref("");
const toolbarConfig = {
excludeKeys: ["insertVideo", "insertImage"],
};
const editorConfig = { placeholder: "请输入内容...", MENU_CONF: {} };
editorConfig.MENU_CONF["uploadImage"] = {
// 自定义上传
async customUpload(file, insertFn) {
const formData = new FormData();
console.log(1,file);
formData.append("file", file);
fileUp(formData).then((res) => {
if (res.data.code === 200) {
// 最后插入图片 url alt href
insertFn(import.meta.env.VITE_FILE_PATH+res.data.data, file.name, import.meta.env.VITE_FILE_PATH+res.data.data);
}
});
},
};
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
};
const discussSettings = ref("");
request(DISCUSS_LIST, {
type,
id,
}).then(e=>{
discussSettings.value = e.data.discussDtoList[0].discussSettings;
state.info = e.data;
getPostList(e.data.discussDtoList[0].id);
}).catch(err=>{
console.log(err)
})
// 获取帖子
function getPostList(discussId) {
console.log('获取帖子参数', {
"pid": discussId,
"current": state.pageNo,
"order": 1
})
request(
PostList,
{
"pid": discussId,
"current": state.pageNo,
"order": state.content
}).then(e=>{
console.log('我是当前讨论下的帖子',e)
state.postList = e.data.records;
state.total = Number(e.data.total);
}).catch(err=>{
console.log(err)
})
}
// 最新
function nowPost(discussId) {
state.content = 1;
state.searchType = 1;
state.pageNo = 1;
state.currentPage = 1;
getPostList(discussId);
}
// 最热
function hotPost(discussId) {
state.content = 2;
state.searchType = 2;
state.pageNo = 1;
state.currentPage = 1;
getPostList(discussId);
}
// 分页
function handleCurrentChange(e, k) {
console.log('分页打印', e, k)
state.currentPage = e;
state.pageNo = e;
getPostList(state.info.discussDtoList[0].id);
}
// 评论点击跳转
function comment({ discussId: id, id: postID }) {
router.push({ path: "discussdetail", query: { id, type, pName, sName, postID, postName:state.info.discussDtoList[0].discussName, discussSettings:discussSettings.value } });
}
// 帖子点赞
function like(d) {
d.praised ? ((d.praiseNum) = Number(d.praiseNum) - 1) : ((d.praiseNum) = Number(d.praiseNum) + 1);
d.praised = !d.praised;
console.log('我是点赞传递的参数', { targetId: d.id, type: 2 })
request(PostPraise, { targetId: d.id, type: 3 }).then(res=>{
console.log('我是点赞的操作',res)
}).catch(err=>{
console.log(err)
});
}
// 帖子收藏
function collection(d) {
d.collected ? ((d.collectionNum) = Number(d.collectionNum) - 1) : ((d.collectionNum) = Number(d.collectionNum) + 1);
d.collected = !d.collected;
console.log('我是收藏传递的参数', { targetId: d.id, type: 2 })
request(PostPraise, { targetId: d.id, type: 4 }).then(res=>{
console.log('我是收藏的操作',res)
}).catch(err=>{
console.log(err)
});
}
// 发表帖子弹框显示
function showPostModal() {
dialogVisible.value = true;
// 隐藏视频上传
setTimeout(() => {
let nodeChilds = document.getElementsByClassName('w-e-bar-item');
nodeChilds[31].style.display = 'none';
}, 200);
}
// 取消发布
function cancelPost() {
dialogVisible.value = false;
}
// 发表帖子发布操作
const postAdd = () => {
if(titleName.value==''){
return ElMessage.warning("评论标题为空");
}
loading.value = ElLoading.service({
lock: true,
text: "Loading",
background: "rgba(0, 0, 0, 0.7)",
});
console.log('用户信息', userInfo.value)
let obj = {
"collectionNum": 0,
"commentNum": 0,
"content": valueHtml.value,
"ctime": "",
"discussId": state.info.discussDtoList[0].id,
"id": 0,
"type": type,
"taskId": id,
"mtime": "",
"praiseNum": 0,
"status": 0,
"title": titleName.value,
"userAvatar": userInfo.value.avatar,
"userId": userInfo.value.id,
"userJobName": userInfo.value.jobName,
"userName": userInfo.value.realName,
"userOrgName": userInfo.value.orgName
}
console.log('发表帖子传递的参数', obj)
request(PostAdd,obj).then(res=>{
console.log(res)
if(res.code==200){
dialogVisible.value = false;
ElMessage.success("发帖成功");
getPostList(state.info.discussDtoList[0].id);
titleName.value = "";
valueHtml.value = "";
loading.value.close()
}
}).catch(err=>{
console.log(err)
ElMessage.error("发帖失败");
loading.value.close()
})
}
</script>
<style scoped lang="scss">
.clearfix:before,
.clearfix:after {
content: "";
display: table;
clear: both;
}
.preNext {
position: absolute;
right: 0px;
.content {
font-size: 14px;
color: #fff;
width: 43px;
height: 14px;
display: inline-block;
position: relative;
top: -6px;
cursor: pointer;
}
.btn {
width: 23px;
height: 23px;
border-radius: 50%;
border: 0;
cursor: pointer;
}
.btn01 {
background-image: url("../../assets/image/prev.png");
}
.btn02 {
background-image: url("../../assets/image/next.png");
}
}
.active {
color: #2478ff;
}
.surveydetail {
.crumb {
color: #fff;
display: flex;
font-size: 14px;
line-height: 24px;
}
.return{
position: absolute;
right: 10%;
.text{
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
}
}
.prevnext {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 500;
color: #ffffff;
.prev {
display: flex;
align-items: center;
cursor: pointer;
}
}
.title {
font-size: 20px;
font-weight: 800;
color: #ffffff;
line-height: 24px;
margin-top: 17px;
margin-left: -11px;
}
.bascinfo {
min-height: 800px;
width: 100%;
background: #ffffff;
border-radius: 8px;
margin-top: 24px;
display: block;
.middletitle {
display: flex;
margin-top: 64px;
position: relative;
.title {
font-size: 24px;
font-weight: 800;
color: #4a9cf8;
margin-left: 79px;
margin-right: 210px;
}
@media screen and (max-width: 1574px) {
.title {
margin-bottom: -24px;
}
}
.btn {
cursor: pointer;
position: absolute;
width: 146px;
height: 46px;
background: #2478ff;
box-shadow: 0px 1px 8px 0px rgba(56, 125, 247, 0.7);
border-radius: 4px;
border: 0;
font-size: 16px;
font-weight: 800;
color: #ffffff;
right: 45px;
top: 5px;
}
}
.line {
display: flex;
margin: 47px 45px 0 75px;
//max-width: 1810px;
// height: 50px;
background: #f9f9f9;
position: relative;
.linetitle {
margin: 14px 120px 17px 28px;
font-size: 16px;
font-weight: 800;
color: #333333;
}
.radi {
position: absolute;
width: 11px;
height: 11px;
border: 2px solid #0060ff;
border-radius: 50%;
margin-top: 19px;
right: 91px;
}
.intime {
position: absolute;
margin-top: 15px;
font-size: 16px;
font-family: PingFang SC;
font-weight: 800;
color: #0060ff;
right: 36px;
}
}
.allbtn {
margin-top: 21px;
margin-left: 105px;
.active {
background: #387df7 !important;
color: #ffffff !important;
}
.btnone {
width: 44px;
height: 26px;
border-radius: 4px;
border: 0;
background-color: #fff;
font-size: 14px;
font-weight: 500;
color: #6e7b84;
cursor: pointer;
}
.btntwo {
font-size: 14px;
font-weight: 500;
color: #6e7b84;
background-color: #fff;
border: 0;
cursor: pointer;
}
}
.discusslist {
margin-left: 105px;
margin-top: 39px;
.itemtitle {
font-size: 16px;
font-weight: 500;
color: #333333;
margin-right: 88px;
cursor: pointer;
}
.itemdiscuss {
margin-top: 15px;
width: 812px;
height: 39px;
font-size: 14px;
font-weight: 500;
color: #666666;
line-height: 24px;
cursor: pointer;
}
.allstar {
display: flex;
margin-top: 18px;
// margin-left: 105px;
.sameone {
width: 14px;
height: 14px;
}
.count {
margin-left: 7px;
font-size: 14px;
font-weight: 500;
color: #b3bdc4;
}
.pinglun {
background-image: url(../../assets/image/pinglun.png);
}
.dianzan {
margin-left: 19px;
background-image: url(../../assets/image/dianzan2.png);
}
.shoucang {
margin-left: 19px;
background-image: url(../../assets/image/shoucang.png);
}
}
.thinline {
// max-width: 1450px;
width: calc(100% - 88px);
margin-top: 33px;
border-top: 1px solid #999999;
opacity: 0.2;
}
}
}
}
</style>