留言板功能部分实现

This commit is contained in:
fan 2020-11-16 19:26:23 +08:00
parent c63f8097e7
commit 1de24c5d31
6 changed files with 251 additions and 16 deletions

18
src/api/learn.js Normal file
View File

@ -0,0 +1,18 @@
import request from '@/utils/request';
// 分页查询帖子回复
export function queryPostPaging(postId, params) {
return request({
url: `/api/learn/${postId}/message/query/paged`,
method: 'get',
params: params
});
}
// 回复帖子
export function answerPost(data) {
return request({
url: `/api/learn/message/create`,
method: 'post',
data: data
});
}

BIN
src/assets/bg_board.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -4,7 +4,8 @@
ref="editor"
v-model="content"
:options="options"
:style="{height: height+'px', 'margin-bottom': '80px'}"
style="background-color: #fff"
:style="{height: height+'px', 'margin-bottom': marginBottom+'px'}"
@change="onChange"
@blur="onBlur"
@focus="onFocus"
@ -13,9 +14,10 @@
</template>
<script>
import { quillEditor } from 'vue-quill-editor';
import { quillEditor, Quill } from 'vue-quill-editor';
import 'quill/dist/quill.snow.css';
import { ImageExtend, QuillWatch} from 'quill-image-extend-module';
Quill.register('modules/ImageExtend', ImageExtend);
export default {
components: {
quillEditor
@ -32,12 +34,66 @@ export default {
placeholder: {
type: String,
default: ''
},
marginBottom: {
type: Number,
default: 80
},
unloadImg: {
type: Boolean,
default: false
},
noHandleP: {
type: Boolean,
defalut: false
}
},
data() {
return {
content: '',
options: {
content: ''
};
},
computed: {
editor() {
return this.$refs.editor.quill;
},
options() {
return this.unloadImg ? {
modules: {
ImageExtend: {
loading: true,
name: 'file',
size: 3,
action: `https://test.joylink.club/jlfile/api/upload/PICTURE?appId=00001&appSecret=joylink00001`,
response: (res) => {
return `https://test.joylink.club/oss/joylink${res.data}`;
}
},
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike'],
[],
[],
[{'list': 'ordered'}, {'list': 'bullet'}],
[{'script': 'sub'}, {'script': 'super'}],
[{'indent': '-1'}, {'indent': '+1'}],
[{'direction': 'rtl'}],
[{'size': ['small', 'large', 'huge']}],
[{'color': [], 'background': []}],
[{'font': []}],
[{'align': []}],
['clean'],
['image']
],
handlers: {
'image': function () {
QuillWatch.emit(this.quill.id);
}
}
}
},
placeholder: '请输入'
} : {
modules: {
toolbar: [
['bold', 'italic', 'underline', 'strike'],
@ -54,12 +110,7 @@ export default {
['clean']
]
}
}
};
},
computed: {
editor() {
return this.$refs.editor.quill;
};
},
titleConfig () {
return {
@ -91,11 +142,13 @@ export default {
watch: {
'value': function(val) {
this.$nextTick(() => {
if (val != this.$escapeHTML(this.content)) {
if (val != this.$escapeHTML(this.content) && !this.noHandleP) {
this.editor.enable(false);
this.content = val;
this.editor.enable(true);
this.editor.blur();
} else if (this.noHandleP) {
this.content = val;
}
});
}
@ -105,11 +158,18 @@ export default {
},
methods: {
onChange(e) {
this.$emit('input', this.$escapeHTML(this.content));
if (!this.noHandleP) {
this.$emit('input', this.$escapeHTML(this.content));
} else {
this.$emit('input', this.content);
}
},
onBlur(e) {
},
onFocus(e) {
},
getFocus() {
this.$refs.editor.quill.focus();
}
}
};

View File

@ -2,10 +2,10 @@ export function getBaseUrl() {
let BASE_API;
if (process.env.NODE_ENV === 'development') {
// BASE_API = 'https://joylink.club/jlcloud';
BASE_API = 'https://test.joylink.club/jlcloud';
// BASE_API = 'https://test.joylink.club/jlcloud';
// BASE_API = 'http://192.168.8.107:9000'; // 袁琪
// BASE_API = 'http://192.168.8.129:9000'; // 旭强
// BASE_API = 'http://192.168.8.109:9000'; // 张赛
BASE_API = 'http://192.168.8.119:9000'; // 张赛
// BASE_API = 'http://192.168.8.110:9000'; // 杜康
// BASE_API = 'http://b29z135112.zicp.vip';
// BASE_API = 'http://2925963m2a.zicp.vip'; // 杜康

View File

@ -0,0 +1,150 @@
<template>
<el-dialog
id="elDialog"
title="留言板"
:visible.sync="dialogVisible"
fullscreen
center
:before-close="handleClose"
>
<el-card class="box-card" style="width: 80%;margin-left: 10%;padding: 20px;margin-bottom: 20px;background-color: rgba(255,255,255,0)">
<div v-if="postCommentList.length">
<template v-for="(item,i) in postCommentList">
<div :key="i" style="border: 1px solid #C0C0C0;border-radius: 5px;margin-bottom: 20px;box-shadow: 2px 2px 3px #808080;padding: 10px;background-color: #fff">
<div style="margin-bottom: 10px;display: flex;align-items: center;">
<img :src="avatarUrl(item)" class="head_portrait">
<div style="display: inline-block;margin-right: 20px;margin-left:10px;font-size: 18px;color: #000;">{{ item.creatorNickName }}</div>
<div style="display: inline-block;">{{ item.createTime }}</div>
</div>
<div style="margin-left: 60px;" v-html="$escapeHTML(`${item.content}`)" />
</div>
</template>
</div>
<div v-else style="text-align: center;width: 100%;height: 50px;line-height: 50px;font-size: 18px;color: #ccc;">
<span>暂无评论</span>
</div>
<div style="width: 100%;text-align: center;">
<el-pagination
:current-page.sync="pageNum"
:page-size="pageSize"
layout="total, prev, pager, next,jumper"
:total="total"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<quill-editor ref="quillEditor" v-model="content" style="width: 80%;margin-left: 10%;" placeholder="请输入内容" :margin-bottom="20" :unload-img="true" :noHandleP="true" />
<span id="boardBottom" class="dialog-footer">
<el-button @click="handleClear">清空</el-button>
<el-button type="primary" @click="commitComment">留言</el-button>
<el-button type="danger" @click="dialogVisible = false">返回</el-button>
</span>
<el-button size="mini" type="danger" style="position: fixed; right: 100px;top: 80px;" @click="goSlide">我要留言</el-button>
<div v-show="imgShow" style="position: fixed;width: 100%;height: 100%;left: 0;top: 0;background: rgba(0,0,0,0.5);" @click="handelCloseImg">
<img id="targetImg" src="" style="position: fixed;top: 50%;left: 50%;transform: translate(-50%,-50%);min-width: 500px;max-height: 80%;height: auto;">
</div>
</el-dialog>
</template>
<script>
import { answerPost, queryPostPaging } from '@/api/learn';
export default {
name: 'MessageBoard',
data() {
return {
dialogVisible: false,
content: '',
postCommentList: [],
pageSize: 10,
pageNum: 0,
total: 0,
imgShow: false
};
},
created() {
const that = this;
window.handleZoomImg = function () {
that.imgShow = true;
document.getElementById('targetImg').src = event.target.currentSrc;
};
},
methods: {
handleClose() {
this.dialogVisible = false;
},
doShow() {
this.handleCurrentChange();
this.dialogVisible = true;
},
commitComment() {
const images = this.content.match(/<img/g);
if (images && images.length > 3) {
this.$message.error('留言内容使用图片应小于三张!');
return;
}
answerPost({postId: 1, content: this.content}).then(resp => {
this.handleCurrentChange();
this.$message.success('留言成功 ');
this.content = '';
}).catch(error => {
this.$message.error('留言失败 ');
});
},
handleCurrentChange() {
queryPostPaging(1, {pageSize: this.pageSize, pageNum: this.pageNum}).then(resp => {
this.postCommentList = [];
(resp.data.list || []).forEach(item => {
const value = item.content.replace(/<img/g, '<img style="width: 100px;height: auto;cursor: zoom-in;" onclick="handleZoomImg()"');
item.content = value;
this.postCommentList.push(item);
});
this.total = resp.data.total;
});
},
goSlide() {
const bottom = document.getElementById('boardBottom');
const element = document.getElementById('elDialog').childNodes[0];
element.scrollTop = bottom.offsetTop;
this.$refs.quillEditor.getFocus();
},
avatarUrl(val) {
if (val && val.creatorAvatarPath) {
return 'https://joylink.club/oss/joylink' + val.creatorAvatarPath;
} else {
return 'https://joylink.club/oss/wxmicro_assistant/userhead/defaultuser.png';
}
},
handleClear() {
this.content = '';
},
handelCloseImg() {
this.imgShow = false;
document.getElementById('targetImg').src = '';
}
}
};
</script>
<style scoped>
.dialog-footer{
margin: 0 auto;
display: flex;
justify-content: center;
}
.head_portrait{
width: 50px;
height: 50px;
border-radius: 25px;
}
.img-box{
width: 100px;
height: auto;
}
/deep/.el-dialog.is-fullscreen{
background-image:url('../../../../assets/bg_board.jpg');
}
/deep/.ql-container{
height: 80%;
}
</style>

View File

@ -24,6 +24,7 @@
<!-- <el-button v-if="isContest" size="small" @click=" fieldExam">实操测验</el-button> -->
<el-button v-if="isContest" size="small" @click="goTheoryQuiz">理论考试</el-button>
<el-button v-if="isContest" size="small" @click="viewChangeMap">切换地图</el-button>
<el-button size="small" @click="messageBoardShow">留言板</el-button>
<template v-if="project === 'bjd'">
<el-button v-if="running" size="small" @click="viewRunPlan">{{ $t('joinTraining.runGraphPreview') }}</el-button>
<el-button v-if="!running" size="small" type="warning" @click="loadRunPlan">{{ $t('joinTraining.runGraphLoading') }}</el-button><!-- 运行图加载 -->
@ -43,6 +44,7 @@
<scheduling-view v-if="schedulePreviewShow" ref="schedulingView" :group="group" />
<change-map v-if="isContest" ref="changeMap" @changeMap="changeMap" />
<qr-code ref="qrCode" />
<message-board ref="messageBoard" />
</div>
</template>
<script>
@ -56,6 +58,7 @@ import SchedulingView from '@/views/newMap/displayNew/demon/schedulingView';
import { EventBus } from '@/scripts/event-bus';
import DistributeDraft from '@/views/components/limits/distribute';
import QrCode from '@/components/QrCode';
import MessageBoard from './demon/messageBoard';
export default {
name:'DemonMenu',
components:{
@ -65,7 +68,8 @@ export default {
SchedulingView,
ChangeMap,
DistributeDraft,
QrCode
QrCode,
MessageBoard
},
props:{
isAllShow:{
@ -286,6 +290,9 @@ export default {
if (this.$refs) {
this.$refs.distribute.doShow({PermissionType:'03', mapId: this.$route.query.mapId, prdType: this.$route.query.prdType});
}
},
messageBoardShow() {
this.$refs.messageBoard.doShow();
}
}
};