Files
laws-sinotruk-client/src/views/documentTool/documentComparison/DocumentDataComparison.vue
T
2023-11-08 15:36:59 +08:00

762 lines
23 KiB
Vue

<template>
<internal-detail-page :title="$t('docTool.comparison.documentComparison')"
:content-padding="0"
:loading="loading"
need-custom-back-func
@back="handleBack">
<template v-slot:titleRightCustom>
<!--查看比对结果-->
<a-button class="header-btn"
type="primary"
icon="eye"
ghost
@click="viewTheComparisonResultsClick"
v-has="'docComparison:dataComparison:viewTheComparisonResults'">
{{ $t('docTool.comparison.viewTheComparisonResults') }}
</a-button>
<!--添加全文评论-->
<a-button class="header-btn"
type="primary"
icon="message"
ghost
@click="addFullTextCommentClick"
v-has="'docComparison:dataComparison:addFullTextComment'">
{{ $t('docTool.comparison.addFullTextComment') }}
</a-button>
<!--关闭/打开自动匹配-->
<a-button class="header-btn"
type="primary"
:icon="isMatching?'close-circle':'check-circle'"
ghost
@click="turnOffAutomaticMatchingClick"
v-has="'docComparison:dataComparison:turnOffAutomaticMatching'">
{{ isMatching ? $t('docTool.comparison.turnOffAutomaticMatching') : $t('docTool.comparison.turnOnAutoMatch') }}
</a-button>
</template>
<div class="can-scroll-content">
<div class="detail-content">
<!--左边的文档-->
<div class="detail-content-left">
<!--左边的目录-->
<div class="standard-catalogue part-common" :class="{'hide-catalogue': !leftCatalogueShow}">
<div class="catalogue-show" @click="changeLeftCatalogueShow">
<a-icon :type="leftCatalogueShow ? 'left' : 'right'" />
</div>
<div class="part-title" v-show="leftCatalogueShow">{{ $t('standardRegulationLibrary.standardCatalogue') }}</div>
<div class="has-title-part-content" v-show="leftCatalogueShow">
<a-tree
class="draggable-tree"
:selected-keys="leftTreeSelectedKeys"
:replace-fields="{key: 'menuId'}"
@select="onSelectLeft"
:tree-data="resultData.menuLeft">
<a-icon slot="switcherIcon" type="down" :style="{ fontSize: '12px', color: '#103770' }" />
<template slot="title" slot-scope="{title}">
<!-- 目录前三个和有子集的标题加粗 -->
<span :style="title.indexOf('.')===-1?'font-weight: 600;':''">{{ title }}</span>
</template>
</a-tree>
</div>
</div>
<!--左侧标准信息-->
<div class="detail-content-left-container">
<!--标准名称-->
<div class="standard-name">
<a-tooltip placement="topLeft">
<template #title>
{{ resultData.serialNumberLeft }} {{ resultData.fileNameLeft }}
</template>
<span>{{ resultData.serialNumberLeft }} {{ resultData.fileNameLeft }}</span>
</a-tooltip>
</div>
<div class="detail-content-left-scroll">
<div class="detail-content-left-item" @click="detailLeft(index,item)"
v-for="(item,index) in resultData.textLeft" :key="index"
:class="{'detail-content-item-selected': leftHighlightMenuId === item.menuId,'detail-content-item-saved':item.reviewed + '' === '1'}">
<div class="detail-content-item-text" style="margin-bottom: 10px;color: #040B29">
{{ item.itemsNum + ' ' + item.itemsName }}
</div>
<div class="detail-content-item-text" v-html="item.itemsText"></div>
</div>
</div>
</div>
</div>
<!--右侧文档-->
<div class="detail-content-right">
<!--右侧目录-->
<div class="standard-catalogue part-common" :class="{'hide-catalogue': !rightCatalogueShow}">
<div class="catalogue-show" @click="changeRightCatalogueShow">
<a-icon :type="rightCatalogueShow ? 'left' : 'right'" />
</div>
<div class="part-title" v-show="rightCatalogueShow">{{ $t('standardRegulationLibrary.standardCatalogue') }}</div>
<div class="has-title-part-content" v-show="rightCatalogueShow">
<a-tree
class="draggable-tree"
:selected-keys="rightTreeSelectedKeys"
:replace-fields="{key: 'menuId'}"
@select="onSelectRight"
:tree-data="resultData.menuRight">
<a-icon slot="switcherIcon" type="down" :style="{ fontSize: '12px', color: '#103770' }" />
<template slot="title" slot-scope="{title}">
<!-- 目录前三个和有子集的标题加粗 -->
<span :style="title.indexOf('.')===-1?'font-weight: 600;':''">{{ title }}</span>
</template>
</a-tree>
</div>
</div>
<!--右侧标准信息-->
<div class="detail-content-right-container">
<!--标准名称-->
<div class="standard-name">
<a-tooltip placement="topLeft">
<template #title>
{{ resultData.serialNumberRight }} {{ resultData.fileNameRight }}
</template>
<span>{{ resultData.serialNumberRight }} {{ resultData.fileNameRight }}</span>
</a-tooltip>
</div>
<div class="detail-content-right-scroll">
<div class="detail-content-right-item" @click="detailRight(index,item)"
v-for="(item,index) in resultData.textRight" :key="index"
:class="{'detail-content-item-selected': item.menuId === rightHighlightMenuId, 'detail-content-item-saved':item.reviewed + '' === '1'}">
<div class="detail-content-item-text" style="margin-bottom: 10px;color: #040B29">
{{ item.itemsNum + ' ' + item.itemsName }}
</div>
<div class="detail-content-item-text" v-html="item.itemsText">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="remarks">
<a-form-model :model="formInline" class="formAdd" :rules="rules" ref="ruleForm">
<div class="box-title-text-remarks">
<div class="title-text-remarks" :title="$t('docTool.comparison.comparisonOfArticles')" style="width: 84px">
<span>{{ $t('docTool.comparison.comparisonOfArticles') }}</span>
</div>
<a-form-model-item class="item-model" prop="comment">
<a-textarea :placeholder="$t('pleaseEnter')+$t('docTool.comparison.comparisonOfArticles')"
v-model="formInline.comment"
:maxLength="500"
:rows="3" />
</a-form-model-item>
</div>
</a-form-model>
</div>
</div>
<div class="submit-button">
<!--一致-->
<a-button style="margin-right: 10px"
type="primary"
@click="consistentAssessmentClick"
v-has="'docComparison:dataComparison:consistentAssessment'">
{{ $t('docTool.comparison.consistentAssessment') }}
</a-button>
<!--保存-->
<a-button type="primary" @click="submit" v-has="'docComparison:dataComparison:save'">{{ $t('preservation') }}</a-button>
</div>
<!--全文评论-->
<comparison-add-full-comment ref="comparisonAddFullComment" />
</internal-detail-page>
</template>
<script>
// 添加全文评论弹框
import ComparisonAddFullComment from './modules/ComparisonAddFullComment.vue'
import InternalDetailPage from '../../../components/InternalDetailPage.vue'
import { docComparsionConsistentAndSave, getComparisonDetail, clauseComparison } from '../../../api/documentToolApi.js'
export default {
name: 'DocumentDataComparison',
components: { ComparisonAddFullComment, InternalDetailPage },
data () {
return {
formInline: {},
loadingText: false,
rules: {},
loading: false,
resultData: {},
isMatching: true, // 自动匹配是否开启
dataLeft: {},
dataRight: {},
pageFrom: null,
leftCatalogueShow: true, // 左侧的标准目录是否展示
rightCatalogueShow: true, // 右侧的标准目录是否展示
leftTreeSelectedKeys: [], // 左侧被选中树节点
rightTreeSelectedKeys: [], // 右侧被选中树节点
leftHighlightMenuId: null, // 左侧高亮数据的menuId
rightHighlightMenuId: null // 右侧高亮数据的menuId
}
},
mounted () {
this.getData()
document.title = this.$t('docTool.comparison.documentComparison') + ' - ' + this.$t('edit')
},
methods: {
// 文档对比的一致按钮点击
consistentAssessmentClick () {
if (!this.dataLeft.id && !this.dataRight.id) {
this.$message.warning(this.$t('docTool.comparison.pleaseSelectTheDataCompared'))
return
}
const query = {
itemsIdLeft: this.dataLeft.id,
itemsIdRight: this.dataRight.id,
infoId: this.$route.query.id,
comment: '一致'
}
this.loading = true
docComparsionConsistentAndSave(query).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.formInline = {}
// 保存之后会有一个淡蓝色的边框
if (this.leftHighlightMenuId === this.dataLeft.menuId) {
this.leftHighlightMenuId = null
}
if (this.rightHighlightMenuId === this.dataRight.menuId) {
this.rightHighlightMenuId = null
}
this.resultData.textRight.forEach(val => {
if (val.id === this.dataRight.id) {
val.reviewed = '1'
}
})
this.resultData.textLeft.forEach(val => {
if (val.id === this.dataLeft.id) {
val.reviewed = '1'
}
})
this.resultData = { ...this.resultData }
this.dataLeft = {}
this.dataRight = {}
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
// 文档对比的保存按钮点击
submit () {
if (!this.dataLeft.id && !this.dataRight.id) {
this.$message.warning(this.$t('docTool.comparison.pleaseSelectTheDataCompared'))
return
}
this.$refs.ruleForm.validate(valid => {
if (valid) {
const query = {
itemsIdLeft: this.dataLeft.id,
itemsIdRight: this.dataRight.id,
infoId: this.$route.query.id,
comment: this.formInline.comment
}
this.loading = true
docComparsionConsistentAndSave(query).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.formInline = {}
// 保存之后会有一个淡蓝色的边框
if (this.leftHighlightMenuId === this.dataLeft.menuId) {
this.leftHighlightMenuId = null
}
if (this.rightHighlightMenuId === this.dataRight.menuId) {
this.rightHighlightMenuId = null
}
this.resultData.textRight.forEach(val => {
if (val.id === this.dataRight.id) {
val.reviewed = '1'
}
})
this.resultData.textLeft.forEach(val => {
if (val.id === this.dataLeft.id) {
val.reviewed = '1'
}
})
this.resultData = { ...this.resultData }
this.dataLeft = {}
this.dataRight = {}
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
}
})
},
// 查看对比结果按钮点击
viewTheComparisonResultsClick () {
this.$router.push({
path: '/documentTool/ComparisonResults',
query: {
id: this.$route.query.id,
isDisplay: 2
}
})
},
// 添加全文评论按钮点击
addFullTextCommentClick () {
const query = {
id: this.$route.query.id
}
getComparisonDetail(query).then((res) => {
if (res.success) {
this.$refs.comparisonAddFullComment.open(res.result.comments || '')
}
})
},
// 关闭自动匹配、开启自动匹配
turnOffAutomaticMatchingClick () {
this.isMatching = !this.isMatching
this.$message.success(this.$t('operationSuccessful'))
},
// 获取文件对比详情
getData () {
const query = {
id: this.$route.query.id
}
this.loading = true
getComparisonDetail(query).then((res) => {
if (res.success) {
this.resultData = res.result || {}
} else {
this.resultData = {}
}
}).finally(() => {
this.loading = false
})
},
// 点击左侧文档内容
detailLeft (num, item) {
this.leftTreeSelectedKeys = [item.menuId]
if (item.id === this.dataLeft.id && !this.isMatching) {
this.dataLeft = {}
this.leftHighlightMenuId = null
return
}
this.leftHighlightMenuId = item.menuId
this.dataLeft = item
this.dataLeft.numIndex = num
// 自动匹配,右侧数据需要跳转
if (this.isMatching) {
const index = this.dataLeft.targetStand
if (index > -1) {
this.dataRight = this.resultData.textRight[index]
this.dataRight.numIndex = index
this.rightHighlightMenuId = this.dataRight.menuId
this.rightTreeSelectedKeys = [this.dataRight.menuId]
this.handleJumpRightData(index)
this.clauseComparison()
}
}
},
// 点击右侧文档内容
detailRight (num, item) {
this.rightTreeSelectedKeys = [item.menuId]
if (item.id === this.dataRight.id && !this.isMatching) {
this.dataRight = {}
this.rightHighlightMenuId = null
return
}
this.dataRight = item
this.dataRight.numIndex = num
this.rightHighlightMenuId = item.menuId
if (this.isMatching) {
const index = this.dataRight.targetStand
if (index > -1) {
this.dataLeft = this.resultData.textLeft[index]
this.dataLeft.numIndex = index
this.leftHighlightMenuId = this.dataLeft.menuId
this.leftTreeSelectedKeys = [this.dataLeft.menuId]
this.handleJumpLeftData(index)
this.clauseComparison()
}
}
},
// 自动匹配
clauseComparison () {
const query = {
leftId: this.dataLeft.id,
rightId: this.dataRight.id
}
this.loadingText = true
clauseComparison(query).then((res) => {
if (res.success) {
this.loadingText = false
this.resultData.textLeft[this.dataLeft.numIndex].itemsText = res.result[0]
this.resultData.textRight[this.dataRight.numIndex].itemsText = res.result[1]
} else {
this.loadingText = false
}
})
},
// 左侧树选择
onSelectLeft (selectedKeys, exports) {
const node = exports.node.$vnode.data.props.dataRef
const index = this.resultData.textLeft.findIndex(tt => tt.menuId === node.menuId)
this.dataLeft = this.resultData.textLeft[index]
console.log(this.dataLeft)
this.dataLeft.numIndex = index
this.leftHighlightMenuId = this.dataLeft.menuId
this.leftTreeSelectedKeys = [this.dataLeft.menuId]
this.handleJumpLeftData(index)
// 处理选中右侧树
if (this.isMatching) {
const indexRight = this.dataLeft.targetStand
if (indexRight > -1) {
this.dataRight = this.resultData.textRight[indexRight]
this.dataRight.numIndex = indexRight
this.rightHighlightMenuId = this.dataRight.menuId
this.rightTreeSelectedKeys = [this.dataRight.menuId]
this.handleJumpRightData(indexRight)
this.clauseComparison()
}
}
},
// 右侧树选中
onSelectRight (selectedKeys, exports) {
debugger
const node = exports.node.$vnode.data.props.dataRef
const index = this.resultData.textRight.findIndex(tt => tt.menuId === node.menuId)
this.dataRight = this.resultData.textRight[index]
this.dataRight.numIndex = index
this.rightHighlightMenuId = this.dataRight.menuId
this.rightTreeSelectedKeys = [this.dataRight.menuId]
this.handleJumpRightData(index)
// 处理选中左侧树
if (this.isMatching) {
const indexLeft = this.dataRight.targetStand
if (indexLeft > -1) {
this.dataLeft = this.resultData.textLeft[indexLeft]
this.dataLeft.numIndex = indexLeft
this.leftHighlightMenuId = this.dataLeft.menuId
this.leftTreeSelectedKeys = [this.dataLeft.menuId]
this.handleJumpLeftData(indexLeft)
this.clauseComparison()
}
}
},
/**
* 左侧数据跳转
*/
handleJumpLeftData (index) {
if (index > -1) {
const scrollContent = document.getElementsByClassName('detail-content-left-scroll')
const clauseItemDom = document.getElementsByClassName('detail-content-left-item')
scrollContent[0].scrollTop = clauseItemDom[index].offsetTop - 150
}
},
/**
* 右侧数据跳转
*/
handleJumpRightData (index) {
if (index > -1) {
const detailContent = document.getElementsByClassName('detail-content-right-scroll')
const detailRight = document.getElementsByClassName('detail-content-right-item')
detailContent[0].scrollTop = detailRight[index].offsetTop - 150
}
},
handleBack () {
this.$router.push({
path: '/documentTool/documentComparison'
})
},
changeLeftCatalogueShow () {
this.leftCatalogueShow = !this.leftCatalogueShow
},
changeRightCatalogueShow () {
this.rightCatalogueShow = !this.rightCatalogueShow
}
}
}
</script>
<style scoped lang="less">
.header-btn {
margin-left: 12px;
}
.header-btn:first-child {
margin-left: 0;
}
.can-scroll-content {
height: calc(100% - 52px);
overflow: auto;
}
.detail-content {
height: calc(100% - 131px);
background-color: #eff1f4;
}
.detail-content-left {
width: 50%;
float: left;
height: 100%;
border-right: 2px #EFF1F3 solid;
box-sizing: border-box;
border-bottom: 2px #EFF1F3 solid;
display: flex;
}
.detail-content-right {
width: 50%;
height: 100%;
float: left;
box-sizing: border-box;
border-bottom: 2px #EFF1F3 solid;
display: flex;
}
.detail-content-left-header {
width: 100%;
font-size: 16px;
font-family: Blue Sky Noto;
font-weight: 400;
color: #040B29;
margin-bottom: 24px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.box-title-text-remarks {
line-height: 1.4;
display: flex;
/*align-items: center;*/
margin-bottom: 10px;
}
.item-model {
width: calc(100% - 232px);
}
.title-text-remarks {
width: 68px;
color: #000F16;
display: inline-block;
font-weight: 500;
font-size: 14px;
margin-right: 16px;
margin-top: 6px;
text-align: right;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.box-button {
height: 38px;
/*margin-top: 2px;*/
}
.remarks {
margin-top: 20px;
width: 50%;
display: inline-block;
padding: 0 32px;
box-sizing: border-box;
}
.itemModel {
width: calc(100% - 232px);
}
.submit-button {
height: 52px;
text-align: right;
padding: 10px 24px;
}
.detail-content-left-container {
height: 100%;
overflow-y: auto;
transition: all 1s;
scroll-behavior: smooth;
flex: 1;
}
.detail-content-right-container {
height: 100%;
overflow-y: auto;
transition: all 1s;
scroll-behavior: smooth;
flex: 1;
.standard-name {
margin-right: 0;
}
}
.detail-content-left-scroll {
height: calc(100% - 25px - 40px);
width: calc(100% - 20px);
display: inline-block;
margin: 0 10px 0 10px;
overflow: auto;
background-color: white;
}
.detail-content-right-scroll {
height: calc(100% - 25px - 40px);
width: calc(100% - 10px);
display: inline-block;
margin-left: 10px;
overflow: auto;
background-color: white;
}
.detail-content-left-item {
padding: 16px 20px;
box-sizing: border-box;
border: 1px solid #EFF1F3;
cursor: pointer;
background-color: white;
}
.detail-content-right-item {
padding: 16px 20px;
box-sizing: border-box;
border: 1px solid #EFF1F3;
cursor: pointer;
background-color: white;
}
.detail-content-left-item:last-child {
margin-bottom: 0;
}
.detail-content-item-text {
font-size: 16px;
font-weight: 400;
color: #040B29;
word-break: break-word;
/deep/ table {
width: 100%;
}
/deep/ img {
max-width: 100%;
}
}
.detail-content-item-selected {
border: 2px red solid !important;
}
.detail-content-item-saved {
border: 2px #21c9cc solid;
}
::v-deep .delClass {
color: #ff7168;
}
::v-deep .insertClass {
color: green;
}
/deep/ .ant-tree li span.ant-tree-switcher {
float: right;
}
::-webkit-scrollbar {
width: 3px;
}
.part-common {
border-radius: 8px;
background: #FFFFFF;
}
.standard-catalogue {
height: calc(100% - 20px);
width: 200px;
margin: 10px 10px 10px 0;
position: relative;
transition: width .2s linear;
/deep/ .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected {
background-color: transparent !important;
color: @primary-color;
}
.catalogue-show {
position: absolute;
width: 12px;
height: 24px;
left: 100%;
top: 50%;
transform: translateY(-50%);
background-color: @primary-color;
border-radius: 0 12px 12px 0;
cursor: pointer;
color: white;
.anticon {
left: -2px;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
}
.hide-catalogue {
width: 0;
min-width: 0;
}
.part-title {
height: 40px;
background: rgba(213, 44, 38, 0.12);
border-radius: 8px 8px 0 0;
line-height: 40px;
padding: 0 24px;
font-size: 16px;
font-family: PingFang SC-Semibold, PingFang SC, sans-serif;
font-weight: 600;
color: #1D2129;
white-space: nowrap;
overflow: hidden;
}
.has-title-part-content {
height: calc(100% - 40px);
overflow: auto;
padding: 0 20px;
}
.standard-name {
margin: 10px 10px 5px 10px;
height: 40px;
background: #FFFFFF;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
}
.standard-name > span {
font-size: 16px;
font-family: PingFang SC-Semibold, PingFang SC, sans-serif;
font-weight: 600;
color: #1D2129;
flex: 1;
width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
}
</style>