mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/fe-student.git
synced 2025-12-07 09:56:46 +08:00
628 lines
16 KiB
Vue
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>
|