614 lines
20 KiB
Vue
614 lines
20 KiB
Vue
<template>
|
||
<internal-detail-page :title="pageTitle" :loading="loading">
|
||
<div class="detail-page-title">{{ model.title }}</div>
|
||
<div class="detail-page-second-title">
|
||
{{ $t('businessSupport.questionAnswer.poster') + ':' + (model.orgCode_dictText || '') + ' ' + (model.userId_dictText || '') }}
|
||
</div>
|
||
<div class="detail-page-part">
|
||
<div class="detail-page-part-form">
|
||
<!-- 标准号/标准名称 -->
|
||
<div class="detail-page-part-form-item-large">
|
||
<label>{{ $t('standardNumOrName') }}</label>
|
||
<span class="link" @click="clickStandard">{{ model.standardNumber && model.standardName ? model.standardNumber + ' ' + model.standardName : global.emptyLine }}</span>
|
||
</div>
|
||
<!-- 项目 -->
|
||
<div class="detail-page-part-form-item-large">
|
||
<label>{{ $t('project') }}</label>
|
||
<span>{{ model.project_dictText || global.emptyLine }}</span>
|
||
</div>
|
||
<!-- 附件 -->
|
||
<div class="detail-page-part-form-item-large-file">
|
||
<label>{{ $t('businessSupport.questionAnswer.attach') }}</label>
|
||
<template v-if="fileList && fileList.length > 0">
|
||
<div class="file-box">
|
||
<div class="file-list-file" v-for="file in fileList" :key="file.id">
|
||
<div class="file-list-file-info">
|
||
<a-icon type="link" />
|
||
<div class="file-list-file-name" @click="handlePreview(file)">{{ file.fileName }}</div>
|
||
</div>
|
||
<!-- 下载-->
|
||
<a-button type="link" icon="download" class="file-btn" @click="handleDownload(file)">
|
||
{{ $t('download') }}
|
||
</a-button>
|
||
<!-- 无水印下载-->
|
||
<!--<a-button type="link" v-has="btnPermission.unwatermarkedDownload" class="file-btn">-->
|
||
<!-- <i class="iconfont icon-water-drop-slash"></i>-->
|
||
<!-- {{ $t('unwatermarkedDownload') }}-->
|
||
<!--</a-button>-->
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<span v-else>{{ global.emptyLine }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 问题描述部分 -->
|
||
<div class="question-desc-wrapper">
|
||
<p class="question-desc">{{ model.problemDescription }}</p>
|
||
<p class="right-bottom-p">
|
||
<span class="time-span">{{ model.quizTime }}</span>
|
||
<span class="right-bottom-p-span">{{ answerArr.length + $t('businessSupport.questionAnswer.answerNum')}}</span>
|
||
</p>
|
||
</div>
|
||
<!-- 历史回答数据 -->
|
||
<template v-if="answerArr && answerArr.length > 0">
|
||
<div v-for="(item, index) in answerArr" :key="index" class="answer-form-wrapper">
|
||
<div class="answer-form-wrapper-title">
|
||
<a-avatar shape="square" :size="28" :src="getAvatarView(item.avatar)" icon="user"/>
|
||
<p class="user-name">{{ item.departName || '' }} {{ item.name }}</p>
|
||
<p v-if="item.isTop" class="top-p">{{ $t('businessSupport.questionAnswer.top') }}</p>
|
||
</div>
|
||
<div class="answer-form-desc-div">
|
||
<div v-html="item.answerDescription"></div>
|
||
<file-echo :fileIds="item.attach"/>
|
||
</div>
|
||
<p class="operate-bottom-p">
|
||
<span>{{ item.createTime }}</span>
|
||
<!-- 置顶评论的操作按钮 -->
|
||
<template v-if="item.isTop">
|
||
<!-- 取消置顶 -->
|
||
<a class="operate-bottom-p-a" @click="setOrCancelTop(item.id)" v-has="'quiz:detail:topOrCancel'">{{ $t('businessSupport.questionAnswer.cancelTop') }}</a>
|
||
<!-- 删除 : 发帖人、评论人、有置顶权限的用户可以删除 ?? -->
|
||
<!--<a v-if="userInfo.id === model.userId || userInfo.id === item.userId || isHasPermission('quiz:detail:topOrCancel')" v-has="'quiz:detail:deleteAnswer'" class="operate-bottom-p-a" @click="deleteAnswer(item.id)">{{ $t('delete') }}</a>-->
|
||
</template>
|
||
<!-- 非置顶评论 -->
|
||
<template v-else>
|
||
<!-- 设置为置顶 -->
|
||
<a class="operate-bottom-p-a" @click="setOrCancelTop(item.id)" v-has="'quiz:detail:topOrCancel'">{{ $t('businessSupport.questionAnswer.setTop') }}</a>
|
||
<!-- 删除 : 发帖人、评论人、有置顶权限的用户可以删除,置顶的评论不允许删除,取消置顶后允许删除 -->
|
||
<a v-if="userInfo.id === model.userId || userInfo.id === item.userId || isHasPermission('quiz:detail:topOrCancel')" v-has="'quiz:detail:deleteAnswer'" class="operate-bottom-p-a" @click="deleteAnswer(item.id)">{{ $t('delete') }}</a>
|
||
</template>
|
||
</p>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 回答区域 -->
|
||
<div v-if="canAnswer === 1" class="answer-form-wrapper">
|
||
<div class="answer-form-wrapper-title">
|
||
<a-avatar shape="square" :size="28" :src="getAvatarView(currentUser.avatar)" icon="user"/>
|
||
<p class="user-name">{{ currentUser.departIds_dicText || '' }} {{ currentUser.realname }}({{ currentUser.username }})</p>
|
||
<p class="answer_question">{{ $t('businessSupport.questionAnswer.answerQuestion') }}</p>
|
||
</div>
|
||
<u-editor :content="answerDesc" :config="config" ref="ueditor" @editor-onChange="uEditorChange"></u-editor>
|
||
<div class="attach-wrapper">
|
||
<div class="attach-label">{{ $t('attach') }}</div>
|
||
<j-upload v-model="attach" returnId multiple />
|
||
</div>
|
||
<!-- <a-textarea v-model="answerDesc" :autoSize="{minRows: 4}" :maxLength="2000"></a-textarea>-->
|
||
<!-- <p class="answer-desc-num">{{ answerDesc.length }}/2000{{ $t('businessSupport.questionAnswer.word') }}</p>-->
|
||
<a-button class="submit-btn" type="primary" @click="submit" v-has="'quiz:detail:answerSubmit'">{{ $t('submit') }}</a-button>
|
||
</div>
|
||
<!-- 图片预览容器 -->
|
||
<div id="images">
|
||
<div class="image" v-viewer="{movable: false}">
|
||
<img v-show="image" :src="imageUrl">
|
||
</div>
|
||
</div>
|
||
</internal-detail-page>
|
||
</template>
|
||
|
||
<script>
|
||
import { USER_INFO, ACCESS_TOKEN } from '@/store/mutation-types'
|
||
import Vue from 'vue'
|
||
import { getFileAccessHttpUrl, downloadFile } from '@/api/manage'
|
||
import { getQuizById, answerQuiz, setOrCancelTop, deleteAnswer } from '@/api/businessSupport'
|
||
import { getFileInfo } from '@/api/api'
|
||
import { previewPdf } from '@/utils/previewPdf'
|
||
import InternalDetailPage from '@/components/InternalDetailPage'
|
||
import { kkFilePreview } from '@/utils/kkFilePreview'
|
||
import { isHasPermission } from '@/utils/hasPermission'
|
||
import UEditor from '../../../../components/uEditor/UEditor'
|
||
import FileEcho from '../../../../components/FileEcho'
|
||
|
||
// 支持预览的文件后缀
|
||
const CAN_PREVIEW_FILE_SUFFIX = ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx']
|
||
const FILE_TYPE_IMGS = ['jpg', 'jpeg', 'png', 'raw']
|
||
const FILE_TYPE_PDF = 'pdf'
|
||
const Base64 = require('js-base64').Base64
|
||
|
||
export default {
|
||
name: 'AnswerPage',
|
||
components: { FileEcho, InternalDetailPage, UEditor },
|
||
data () {
|
||
return {
|
||
loading: false,
|
||
pageTitle: '',
|
||
model: {},
|
||
answerArr: [],
|
||
fileList: [],
|
||
currentUser: {
|
||
avatar: '',
|
||
realname: '',
|
||
orgCodeTxt: ''
|
||
},
|
||
// UE编辑器配置
|
||
config: {
|
||
// 可以在此处定义工具栏的内容
|
||
toolbars: [
|
||
[
|
||
'undo', // 撤销
|
||
'redo', // 重做
|
||
'bold', // 加粗
|
||
'italic', // 斜体
|
||
'underline', // 下划线
|
||
'strikethrough', // 删除线
|
||
'subscript', // 下标
|
||
'superscript', // 上标
|
||
'fontborder', // 字符边框
|
||
'fontfamily', // 字体
|
||
'fontsize', // 字号
|
||
'forecolor', // 字体颜色
|
||
// 'backcolor', // 背景色
|
||
'paragraph', // 段落格式
|
||
'customstyle', // 自定义标题
|
||
'indent', // 首行缩进
|
||
'justifyleft', // 居左对齐
|
||
'fullscreen', // 全屏
|
||
'justifyright', // 居右对齐
|
||
'justifycenter', // 居中对齐
|
||
'justifyjustify', // 两端对齐
|
||
'lineheight', // 行间距,
|
||
'rowspacingtop', // 段前距
|
||
'rowspacingbottom', // 段后距
|
||
'directionalityltr', // 从左向右输入
|
||
'directionalityrtl', // 从右向左输入
|
||
'cleardoc', // 清空文档
|
||
'formatmatch', // 格式刷
|
||
'removeformat', // 清除格式
|
||
'source', // 源代码
|
||
'blockquote', // 引用
|
||
'pasteplain', // 纯文本粘贴模式
|
||
'selectall', // 全选
|
||
'horizontal', // 分隔线
|
||
'time', // 时间
|
||
'date', // 日期
|
||
'link', // 超链接
|
||
'unlink', // 取消链接
|
||
// 'background', // 背景
|
||
// 'simpleupload', // 单图上传
|
||
'imagenone', // 默认
|
||
'imageleft', // 左浮动
|
||
'imageright', // 右浮动
|
||
'imagecenter', // 居中
|
||
'touppercase', // 字母大写
|
||
'tolowercase', // 字母小写
|
||
'emotion', // 表情
|
||
'spechars', // 特殊字符
|
||
'searchreplace', // 查询替换
|
||
'insertunorderedlist', // 无序列表
|
||
'insertorderedlist', // 有序列表
|
||
'pagebreak', // 分页
|
||
'insertframe', // 插入Iframe
|
||
'charts', // 图表
|
||
'edittip ', // 编辑提示
|
||
'autotypeset', // 自动排版
|
||
'drafts', // 从草稿箱加载
|
||
'inserttable', // 插入表格
|
||
'deletetable', // 删除表格,
|
||
'insertparagraphbeforetable', // ”表格前插入行”
|
||
'insertrow', // 前插入行
|
||
'insertcol', // 前插入列
|
||
'mergeright', // 右合并单元格
|
||
'mergedown', // 下合并单元格
|
||
'deleterow', // 删除行
|
||
'deletecol', // 删除列
|
||
'splittorows', // 拆分成行
|
||
'splittocols', // 拆分成列
|
||
'splittocells', // 完全拆分单元格
|
||
'inserttitle', // 插入标题
|
||
'deletecaption', // 删除表格标题,
|
||
'mergecells', // 合并多个单元格
|
||
'edittable', // 表格属性
|
||
'edittd' // 单元格属性
|
||
]
|
||
],
|
||
autoHeightEnabled: false,
|
||
autoFloatEnabled: false,
|
||
initialContent: '', // 初始化编辑器的内容,也可以通过textarea/script给值,看官网例子
|
||
autoClearinitialContent: true, // 是否自动清除编辑器初始内容,注意:如果focus属性设置为true,这个也为真,那么编辑器一上来就会触发导致初始化的内容看不到了
|
||
initialFrameWidth: '100%',
|
||
elementPathEnabled: false,
|
||
initialFrameHeight: 300,
|
||
maximumWords: 4000,
|
||
BaseUrl: '',
|
||
UEDITOR_HOME_URL: '/ueditor/',
|
||
editTableIndex: 1
|
||
},
|
||
answerDesc: '',
|
||
attach: '', // 回答的附件
|
||
canAnswer: false,
|
||
userInfo: {},
|
||
image: false,
|
||
imageUrl: ''
|
||
}
|
||
},
|
||
mounted () {
|
||
this.initData(this.$route.query.id)
|
||
const userInfo = Vue.ls.get(USER_INFO)
|
||
this.userInfo = userInfo
|
||
this.currentUser = Object.assign({}, userInfo)
|
||
this.canAnswer = Number(this.$route.query.canAnswer)
|
||
if (this.canAnswer === 1) {
|
||
this.pageTitle = this.$t('businessSupport.questionAnswer.answerQuestionTitle')
|
||
} else {
|
||
this.pageTitle = this.$t('businessSupport.questionAnswer.questionDetail')
|
||
}
|
||
},
|
||
methods: {
|
||
isHasPermission,
|
||
// 初始化获取数据信息
|
||
initData (id) {
|
||
this.loading = true
|
||
getQuizById({ id: id }).then(res => {
|
||
if (res.success) {
|
||
this.model = Object.assign({}, res.result)
|
||
if (this.model.file) {
|
||
const fileList = this.model.file.split(',')
|
||
const fileInfoList = []
|
||
fileList.forEach(async id => {
|
||
const fileInfo = await this.getFileInfo(id)
|
||
if (fileInfo) {
|
||
fileInfoList.push(fileInfo)
|
||
}
|
||
})
|
||
this.fileList = fileInfoList
|
||
}
|
||
this.answerArr = this.model.answerList
|
||
}
|
||
}).finally(() => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
// 获取头像
|
||
getAvatarView (avatar) {
|
||
return getFileAccessHttpUrl(avatar)
|
||
},
|
||
getFileInfo (fileId) {
|
||
return new Promise(resolve => {
|
||
let fileInfo
|
||
getFileInfo({ id: fileId }).then(res => {
|
||
if (res.success) {
|
||
fileInfo = res.result
|
||
}
|
||
}).finally(() => {
|
||
resolve(fileInfo)
|
||
})
|
||
})
|
||
},
|
||
handlePreview (file) {
|
||
if (!file || !file.url) {
|
||
return
|
||
}
|
||
// 截取文件后缀名
|
||
const fileSuffix = file.fileName ? file.fileName.split('.')[file.fileName.split('.').length - 1] : ''
|
||
const canPreview = CAN_PREVIEW_FILE_SUFFIX.some(tt => fileSuffix.toLowerCase() === tt)
|
||
// 判断是否为可预览格式的文件
|
||
if (!canPreview) {
|
||
this.$message.loading('该文件类型不支持预览,正在为您准备下载...').then(() => {
|
||
this.handleDownload(file)
|
||
})
|
||
return
|
||
}
|
||
const fileFullUrl = `${window._CONFIG.domianWebSocketURL}/sys/common/view/${file.id}?at=${Vue.ls.get(ACCESS_TOKEN)}&fullfilename=${file.fileName}`
|
||
// 图片预览,使用自己添加的组件
|
||
if (canPreview && FILE_TYPE_IMGS.includes(fileSuffix.toLowerCase())) {
|
||
this.imageUrl = getFileAccessHttpUrl(file.id)
|
||
// 获取viewer实例
|
||
const viewer = this.$el.querySelector('.image').$viewer
|
||
// 调用show方法进行显示预览图
|
||
viewer.show()
|
||
// this.$refs.imagePreviewModal.open(file)
|
||
return
|
||
}
|
||
// pdf预览
|
||
if (canPreview && FILE_TYPE_PDF.includes(fileSuffix.toLowerCase())) {
|
||
const url = previewPdf(file.id)
|
||
console.log(url)
|
||
window.open(url)
|
||
return
|
||
}
|
||
// 其余可预览文件仍使用KKFile进行预览
|
||
kkFilePreview(fileFullUrl)
|
||
},
|
||
handleDownload (file) {
|
||
// 下载文件
|
||
downloadFile(`/laws/standard/common/downloadWithWaterMark/${file.id}`, file.fileName)
|
||
},
|
||
// 点击标准跳转详情
|
||
clickStandard () {
|
||
let path = ''
|
||
// 需要先判断是哪种标准
|
||
if (this.model.type === '1') {
|
||
path = '/standardRegulationLibrary/DomesticStandardDetail'
|
||
} else if (this.model.type === '2') {
|
||
path = '/standardRegulationLibrary/OverseasStandardDetail'
|
||
} else if (this.model.type === '3') {
|
||
path = '/enterpriseStandardLibrary/enterpriseStandardDetail'
|
||
}
|
||
this.$openPageNewSheet({
|
||
path: path,
|
||
query: {
|
||
id: this.model.standardId
|
||
}
|
||
})
|
||
},
|
||
// 获取表格内容
|
||
uEditorChange (val) {
|
||
console.log('--------------uEditorChange------------', val)
|
||
this.answerDesc = val
|
||
},
|
||
submit () {
|
||
if (!this.answerDesc) {
|
||
this.$message.warning(this.$t('businessSupport.questionAnswer.pleaseEnterAnswerDesc'))
|
||
return
|
||
}
|
||
const param = {}
|
||
param.problemId = this.model.id
|
||
param.answerDescription = this.answerDesc
|
||
param.attach = this.attach
|
||
answerQuiz(param).then(res => {
|
||
if (res.success) {
|
||
this.$message.success(res.message)
|
||
this.initData(this.model.id)
|
||
this.$refs.ueditor.execCommand()
|
||
this.answerDesc = ''
|
||
this.attach = ''
|
||
this.$forceUpdate()
|
||
} else {
|
||
this.$message.warning(res.message)
|
||
}
|
||
})
|
||
},
|
||
// 设置或取消置顶
|
||
setOrCancelTop (answerId) {
|
||
setOrCancelTop({ id: answerId }).then(res => {
|
||
if (res.success) {
|
||
this.$message.success(res.message)
|
||
this.initData(this.model.id)
|
||
} else {
|
||
this.$message.warning(res.message)
|
||
}
|
||
})
|
||
},
|
||
// 删除回答
|
||
deleteAnswer (answerId) {
|
||
this.$confirm({
|
||
title: this.$t('confirmDeletion'),
|
||
content: this.$t('areYouSure'),
|
||
onOk: () => {
|
||
deleteAnswer({ id: answerId }).then(res => {
|
||
if (res.success) {
|
||
this.$message.success(res.message)
|
||
this.initData(this.model.id)
|
||
} else {
|
||
this.$message.warning(res.message)
|
||
}
|
||
})
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
|
||
// 二级标题
|
||
.detail-page-second-title {
|
||
font-size: 16px;
|
||
text-align: center;
|
||
font-weight: 550;
|
||
margin-bottom: 20px;
|
||
}
|
||
.detail-page-part-form-item-large {
|
||
width: 100%;
|
||
display: flex;
|
||
margin-bottom: 16px;
|
||
|
||
label {
|
||
width: 10em;
|
||
font-size: 16px;
|
||
font-family: PingFang SC-Regular, PingFang SC, sans-serif;
|
||
font-weight: 400;
|
||
color: #86909C;
|
||
}
|
||
|
||
span {
|
||
white-space: pre-wrap;
|
||
word-break: break-all;
|
||
font-size: 16px;
|
||
font-family: PingFang SC-Regular, PingFang SC, sans-serif;
|
||
color: #1D2129;
|
||
}
|
||
.link {
|
||
color: @primary-color;
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
.detail-page-part-form-item-large-file {
|
||
width: 100%;
|
||
display: flex;
|
||
|
||
label {
|
||
width: 10em;
|
||
font-size: 16px;
|
||
font-family: PingFang SC-Regular, PingFang SC, sans-serif;
|
||
font-weight: 400;
|
||
color: #86909C;
|
||
}
|
||
|
||
a {
|
||
white-space: pre-wrap;
|
||
word-break: break-all;
|
||
font-size: 16px;
|
||
font-family: PingFang SC-Regular, PingFang SC, sans-serif;
|
||
}
|
||
}
|
||
// 问题描述部分
|
||
.question-desc-wrapper {
|
||
border-radius: 8px;
|
||
border: 1px solid #E5E6EB;
|
||
margin-bottom: 20px;
|
||
padding: 20px;
|
||
.question-desc {
|
||
font-size: 16px;
|
||
}
|
||
// 右下角的时间和按钮区域
|
||
.right-bottom-p {
|
||
height: 20px;
|
||
text-align: right;
|
||
margin-bottom: 0;
|
||
.time-span {
|
||
color: #86909C;
|
||
}
|
||
.right-bottom-p-span {
|
||
margin-left: 8px;
|
||
}
|
||
.right-bottom-p-a {
|
||
margin-left: 8px;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 标准信息-附件的文件列表
|
||
.file-box {
|
||
flex: 1;
|
||
width: 0;
|
||
}
|
||
.file-list {
|
||
&-file {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 12px;
|
||
.file-btn {
|
||
padding-right: 0 !important;
|
||
}
|
||
}
|
||
|
||
&-file:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
&-file-info {
|
||
display: flex;
|
||
align-items: center;
|
||
color: @primary-color;
|
||
cursor: pointer;
|
||
flex: 1;
|
||
width: 0;
|
||
}
|
||
|
||
&-file-info > .anticon {
|
||
margin-right: 8px;
|
||
}
|
||
|
||
&-file-name {
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
flex: 1;
|
||
width: 0;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
&-file-operate {
|
||
.ant-btn > .anticon + span, .ant-btn > .iconfont + span {
|
||
margin-left: 10px;
|
||
}
|
||
|
||
.ant-btn:first-child {
|
||
margin-left: 15px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.answer-form-wrapper {
|
||
.answer-form-wrapper-title {
|
||
display: flex;
|
||
.user-name {
|
||
font-weight: 560;
|
||
margin: 0 10px;
|
||
font-size: 16px;
|
||
}
|
||
.answer_question {
|
||
font-size: 16px;
|
||
color: #86909C;
|
||
}
|
||
.top-p {
|
||
color: @primary-color;
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
.answer-form-desc-div {
|
||
border-radius: 8px;
|
||
border: 1px solid #E5E6EB;
|
||
padding: 20px;
|
||
margin-top: 5px;
|
||
}
|
||
.answer-desc-num {
|
||
text-align: right;
|
||
margin-top: 5px;
|
||
margin-bottom: 0;
|
||
}
|
||
.submit-btn {
|
||
margin-top: 20px;
|
||
}
|
||
// 右下角的时间和按钮区域
|
||
.operate-bottom-p {
|
||
height: 20px;
|
||
text-align: right;
|
||
margin: 5px 0 10px 0;
|
||
.time-span {
|
||
color: #86909C;
|
||
}
|
||
.operate-bottom-p-span {
|
||
margin-left: 8px;
|
||
}
|
||
.operate-bottom-p-a {
|
||
margin-left: 8px;
|
||
}
|
||
}
|
||
}
|
||
|
||
/deep/ .edui-default .edui-editor {
|
||
width: 100% !important;
|
||
}
|
||
|
||
/deep/ .edui-default .edui-toolbar {
|
||
line-height: 20px;
|
||
}
|
||
|
||
.attach-wrapper {
|
||
display: flex;
|
||
align-items: baseline;
|
||
margin-top: 20px;
|
||
.attach-label {
|
||
width: 4em;
|
||
font-size: 16px;
|
||
font-family: PingFang SC-Regular, PingFang SC, sans-serif;
|
||
font-weight: 400;
|
||
color: #86909C;
|
||
}
|
||
}
|
||
</style>
|