Files
laws-sinotruk-client/src/views/businessSupport/questionAnswerLibrary/page/AnswerPage.vue
T

614 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>