@@ -20,9 +20,7 @@
< div v-html = "markdownHtml" class="view-body" id="viewBody" ref="viewBody" > < / div >
< / el -tab -pane >
< el-tab-pane label = "编辑" :disabled = "!isEdit" v-if = "isEdit" >
< div class = "lineH25 view-body" contenteditable id = "md-editor" @blur ="emitMarkDown" v-html = "markdown" >
< ! - - < pre id = "viewBody" > < / pre > -- >
< / div >
< div class = "lineH25 view-body" contenteditable id = "md-editor" @blur ="emitMarkDown" v-html = "markdown" > < / div >
< / el -tab -pane >
< / el-tabs >
< / div >
@@ -47,6 +45,9 @@ export default {
prdUrl : ` ` ,
iframeSrc : window . location . origin ,
bboxList : [ ] ,
// 对照表
selectionTable : [ ] , // 表格对照表 记录表格与image_path 关系
selectionImagePath : '' , // 当前表格对应的图片路径
markdown : '' ,
md ,
markdownHtml : '' ,
@@ -55,14 +56,36 @@ export default {
tableActionButtons : [
{
label : '重新识别' ,
icon : 'el-icon-edit ' ,
icon : 'el-icon-view ' ,
click : tableElement => {
console . log ( '重新识别' )
// 获取的 识别图片
this . selectionImagePath = ''
let chooseItem = this . findMatchingTable ( tableElement )
if ( ! this . selectionImagePath ) {
this . $message . error ( '未能识别当前表格图片' )
return false
} else {
// this.finishedMiner = true
this . updateTableAttributes ( tableElement , chooseItem )
let loading = this . $loading ( {
target : tableElement ,
lockScroll : false ,
// spinner: 'element-loading-spinner',
// background: 'rgba(0, 0, 0, 0.8)',
text : 'AI模型分析中....'
} )
setTimeout ( ( ) => {
loading . close ( )
// tableElement.innerHTML = '<div>123</div>'
} , 3000 )
}
}
} ,
{
label : '编辑' ,
icon : 'el-icon-edit' ,
icon : 'el-icon-edit-outline ' ,
click : tableElement => {
this . copyTable = tableElement . innerHTML
tableElement . classList . remove ( 'm-view' )
@@ -76,7 +99,7 @@ export default {
tableActionConfirm : [
{
label : '返回' ,
icon : 'el-icon-edi t' ,
icon : 'el-icon-refresh-lef t' ,
click : tableElement => {
tableElement . classList . add ( 'm-view' )
tableElement . setAttribute ( 'contenteditable' , 'false' )
@@ -122,31 +145,15 @@ export default {
components : { } ,
filters : { } ,
methods : {
// 封装 按钮生成事件
generateButton ( tableElement , buttonContainer , actionButtons ) {
let contenteditable = tableElement . getAttribute ( 'contenteditable' )
let buttons = ! actionButtons ? ( contenteditable === 'false' ? this . tableActionButtons : this . tableActionConfirm ) : actionButtons
// 循环按钮配置
for ( let i = 0 ; i < buttons . length ; i ++ ) {
const button = document . createElement ( 'button' )
button . innerText = buttons [ i ] . label
button . className = 'el-button el-button--primary el-button--mini editor-button'
button . style . pointerEvents = 'auto'
button . addEventListener ( 'click' , ( ) => {
buttons [ i ] . click ( tableElement )
} )
buttonContainer . appendChild ( button )
}
} ,
// 生成视觉模型
viewHtmlModel ( ) {
this . $nextTick ( ( ) => {
const mdHtml = document . getElementById ( 'md-editor' )
// 监听鼠标悬停事件,为表格元素添加浮层按钮
mdHtml . addEventListener ( 'mouseover' , e => {
const tableElement = e . target . closest ( 'table' )
if ( tableElement ) {
// 检查是否已经存在按钮容器
// 检查是否已经存在按钮容器,避免重复创建
let buttonContainer = tableElement . querySelector ( '.md-editor-setting' )
if ( ! buttonContainer ) {
buttonContainer = document . createElement ( 'div' )
@@ -155,6 +162,7 @@ export default {
buttonContainer . style . zIndex = '9999'
buttonContainer . className = 'md-editor-setting'
buttonContainer . setAttribute ( 'contenteditable' , 'false' )
// 调用生成按钮的方法
this . generateButton ( tableElement , buttonContainer )
// 设置按钮位置在表格正中间浮动
const rect = tableElement . getBoundingClientRect ( )
@@ -165,6 +173,7 @@ export default {
}
} )
// 监听鼠标离开事件,移除浮层按钮
mdHtml . addEventListener ( 'mouseout' , e => {
const tableElement = e . target . closest ( 'table' )
if ( ! tableElement || ! tableElement . contains ( e . relatedTarget ) ) {
@@ -176,6 +185,115 @@ export default {
} )
} )
} ,
// 封装 按钮生成事件
generateButton ( tableElement , buttonContainer , actionButtons ) {
// 获取表格的可编辑状态
let contenteditable = tableElement . getAttribute ( 'contenteditable' )
// 根据可编辑状态选择按钮配置
let buttons = ! actionButtons ? ( contenteditable === 'false' ? this . tableActionButtons : this . tableActionConfirm ) : actionButtons
// 循环按钮配置,动态生成按钮并绑定点击事件
for ( let i = 0 ; i < buttons . length ; i ++ ) {
const icon = document . createElement ( 'i' )
const button = document . createElement ( 'button' )
icon . className = ` ${ buttons [ i ] . icon } public-icon `
button . appendChild ( icon )
// 悬浮提示
button . setAttribute ( 'title' , buttons [ i ] . label )
button . className = 'el-button el-button--primary el-button--mini editor-button is-plain'
button . style . pointerEvents = 'auto'
button . addEventListener ( 'click' , ( ) => {
buttons [ i ] . click ( tableElement )
} )
buttonContainer . appendChild ( button )
}
} ,
// 查找匹配的表格
findMatchingTable ( tableElement ) {
let chooseItem = null
let pathId = tableElement . getAttribute ( 'data-path-id' )
if ( pathId ) {
let pathType = tableElement . getAttribute ( 'data-path-type' )
this . selectionImagePath = pathId + pathType
} else {
// 如果没有路径 ID, 则通过表格内容匹配对照表
let tableText = this . getTableText ( tableElement )
chooseItem = this . selectionTable . find ( item => {
if ( item . html ) {
let itemText = this . getTableTextFromHtml ( item . html )
return tableText === itemText
}
return false
} )
if ( chooseItem ) {
this . selectionImagePath = chooseItem . image _path
}
}
return chooseItem
} ,
// 获取表格文本
getTableText ( tableElement ) {
let stringTable = tableElement . innerHTML
let tbodyMatch = stringTable . match ( /<tbody>([\s\S]*)<\/tbody>/ )
if ( tbodyMatch ) {
let newTable = document . createElement ( 'table' )
newTable . innerHTML = tbodyMatch [ 1 ]
return newTable . innerText
}
return ''
} ,
// 从 HTML 中获取表格文本
getTableTextFromHtml ( html ) {
let tableMatch = html . match ( /<table>([\s\S]*)<\/table>/ )
if ( tableMatch ) {
let domTable = document . createElement ( 'table' )
domTable . innerHTML = tableMatch [ 1 ]
return domTable . innerText
}
return ''
} ,
// 更新表格属性
updateTableAttributes ( tableElement , chooseItem ) {
tableElement . setAttribute ( 'data-path-id' , this . selectionImagePath . replace ( /\.[^/.]+$/ , '' ) )
let fileType = this . selectionImagePath . match ( /\.[^/.]+$/ ) [ 0 ]
tableElement . setAttribute ( 'data-path-type' , fileType )
} ,
linesMap ( table ) {
; ( table . blocks ? table . blocks : [ ] ) . map ( lines => {
console . log ( lines )
lines . lines . map ( spans => {
spans . spans . map ( span => {
this . selectionTable . push ( { html : span . html , image _path : span . image _path } )
} )
} )
} )
} ,
setTableSelection ( selection ) {
selection . map ( item => {
if ( item . preproc _blocks && item . preproc _blocks . length > 0 ) {
item . preproc _blocks . forEach ( block => {
if ( block . type === 'table' ) {
this . linesMap ( block )
}
} )
}
// 处理丢弃块
if ( item . discarded _blocks && item . discarded _blocks . length > 0 ) {
item . discarded _blocks . forEach ( block => {
if ( block . type === 'table' ) {
this . linesMap ( block )
}
} )
}
} )
} ,
// 导出
emitMarkDown ( ) {
let pre = document . getElementById ( 'md-editor' ) . innerText
@@ -225,6 +343,10 @@ export default {
getPDFDetailBbox ( ) {
minerUBbox ( { documentId : this . documentId } ) . then ( res => {
this . bboxList = this . formatJson ( JSON . parse ( JSON . stringify ( res . content . content ) ) )
this . setTableSelection ( JSON . parse ( JSON . stringify ( res . content . content ) ) )
console . log ( this . selectionTable , 'this.selectionTable' )
// this.$refs.iframe 重新刷新iframe
this . $refs . iframe . contentWindow . location . reload ( )
this . getPDFDetailMarkDown ( )
@@ -245,7 +367,7 @@ export default {
this . markdown = this . markdown
. replace ( /<table/g , ( ) => {
const uniqueId = ` table- ${ this . tableIdCounter ++ } `
return ` <table contenteditable='false' id=" ${ uniqueId } " class="m-view" `
return ` <table contenteditable='false' class="m-view" `
} )
. replace ( /<script/g , '< script' )
this . markdownHtml = this . md . render ( this . markdown . replace ( /class="m-view"/g , '' ) )