feat(RenderMinerU): 添加表格编辑功能

- 在表格上方添加编辑按钮
- 点击编辑后,表格变为可编辑状态- 编辑完成后,点击返回按钮,表格恢复为只读状态
- 优化了表格渲染逻辑,为每个表格添加唯一ID- 调整了表格样式,使其支持编辑功能
This commit is contained in:
陈昱达
2025-04-14 15:33:14 +08:00
parent b3af3feffe
commit 6c8212b031
9 changed files with 202 additions and 113 deletions

View File

@@ -16,7 +16,9 @@
<div v-html="markdownHtml" class="view-body" id="viewBody" ref="viewBody"></div>
</el-tab-pane>
<el-tab-pane label="编辑">
<div class="lineH25" contenteditable id="md-editor" @blur="emitMarkDown">{{ markdown }}</div>
<div class="lineH25 view-body" contenteditable id="md-editor" @blur="emitMarkDown" v-html="markdown">
<!-- <pre id="viewBody"></pre>-->
</div>
</el-tab-pane>
</el-tabs>
</div>
@@ -36,81 +38,123 @@ export default {
name: 'index',
data() {
return {
tableIdCounter: 0,
prdUrl: ``,
iframeSrc: window.location.origin,
bboxList: [],
markdown: '',
md,
markdownHtml: '',
page: 1
page: 1,
copyTable: null,
tableActionButtons: [
{
label: '重新识别',
icon: 'el-icon-edit',
click: tableElement => {
console.log('重新识别')
}
},
{
label: '编辑',
icon: 'el-icon-edit',
click: tableElement => {
this.copyTable = tableElement.innerHTML
tableElement.classList.remove('m-view')
tableElement.setAttribute('contenteditable', 'true')
let buttonContainer = tableElement.querySelector('.md-editor-setting')
buttonContainer.innerHTML = null
this.generateButton(tableElement, buttonContainer, this.tableActionConfirm)
}
}
],
tableActionConfirm: [
{
label: '返回',
icon: 'el-icon-edit',
click: tableElement => {
tableElement.classList.add('m-view')
tableElement.setAttribute('contenteditable', 'false')
let buttonContainer = tableElement.querySelector('.md-editor-setting')
buttonContainer.innerHTML = null
this.generateButton(tableElement, buttonContainer, this.tableActionButtons)
}
}
// {
// label: '取消',
// icon: 'el-icon-edit',
// click: tableElement => {}
// }
]
}
},
props: {
documentId: {
type: String,
default: '1359571867133448192'
default: '1361351897324294144'
},
isEdit: {
type: Boolean,
default: true
}
},
watch: {},
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() {
// 创建一个唯一的按钮容器
const buttonContainer = document.createElement('div')
buttonContainer.style.position = 'absolute'
buttonContainer.style.pointerEvents = 'none'
// document.body.appendChild(buttonContainer)
this.$nextTick(() => {
const mdHtml = document.getElementById('md-editor')
// 当鼠标滑动view-body下的table 时 增加浮层按钮
window.addEventListener('mouseover', e => {
// 检查是否在 viewBody 内部
const viewBody = document.getElementById('viewBody')
if (viewBody.contains(e.target)) {
// 检查目标元素是否为 table 或其子元素
mdHtml.addEventListener('mouseover', e => {
const tableElement = e.target.closest('table')
if (tableElement) {
// 清除之前的按钮
// buttonContainer.innerHTML = ''
//
// // 在这里添加浮层按钮的逻辑
// console.log('Mouse over table or TD element inside viewBody')
// // 生成两个按钮
// const button = document.createElement('button')
// button.innerText = '标注'
// button.style.position = 'absolute'
// // 按钮位置在表格正中间浮动
// // 设置按钮位置在鼠标位置
// const rect = tableElement.getBoundingClientRect()
// console.log(rect)
// // 按钮s生成在鼠标位置
// button.style.left = `-10px`
// button.style.top = `-10px`
//
// button.style.backgroundColor = 'transparent'
// button.style.border = 'none'
// button.style.cursor = 'pointer'
// button.style.padding = '0'
// button.style.fontSize = '16px'
// button.style.zIndex = '9999'
// button.style.pointerEvents = 'auto'
// button.addEventListener('click', () => {
// alert(1)
// })
// buttonContainer.appendChild(button)
// tableElement.appendChild(buttonContainer)
// 检查是否已经存在按钮容器
let buttonContainer = tableElement.querySelector('.md-editor-setting')
if (!buttonContainer) {
buttonContainer = document.createElement('div')
buttonContainer.style.position = 'absolute'
buttonContainer.style.pointerEvents = 'none'
buttonContainer.style.zIndex = '9999'
buttonContainer.className = 'md-editor-setting'
buttonContainer.setAttribute('contenteditable', 'false')
this.generateButton(tableElement, buttonContainer)
// 设置按钮位置在表格正中间浮动
const rect = tableElement.getBoundingClientRect()
buttonContainer.style.left = `10px` // 调整位置
buttonContainer.style.top = `-20px` // 调整位置
tableElement.appendChild(buttonContainer)
}
}
}
})
})
// 当鼠标离开 view-body 下的 table 时 删除按钮
window.addEventListener('mouseout', e => {
// 检查是否在 viewBody 内部
const viewBody = document.getElementById('viewBody')
if (!viewBody.contains(e.target) || !e.target.closest('table')) {
buttonContainer.innerHTML = ''
}
mdHtml.addEventListener('mouseout', e => {
const tableElement = e.target.closest('table')
if (!tableElement || !tableElement.contains(e.relatedTarget)) {
const buttonContainer = tableElement.querySelector('.md-editor-setting')
if (buttonContainer) {
buttonContainer.remove()
}
}
})
})
},
// 导出
@@ -164,18 +208,23 @@ export default {
})
},
changeTab() {
let pre = document.getElementById('md-editor').innerText
// pre= JSON.stringify(pre)
let copyMdHtml = md.render(pre)
let pre = document.getElementById('md-editor').innerHTML
// pre = JSON.stringify(pre)
// let copyMdHtml = md.render(pre)
// 给 copyMdHtml 里面的table 增加 class m-view
copyMdHtml = copyMdHtml.replace(/<table/g, '<table class="m-view"')
this.markdownHtml = copyMdHtml
// copyMdHtml = copyMdHtml.re
this.markdownHtml = md.render(pre.replace(/class="m-view"/g, ''))
},
async getPDFDetailMarkDown() {
const response = await fetch(minerUMarkDown({ documentId: this.documentId }))
this.markdown = await response.text()
this.markdownHtml = this.md.render(this.markdown).replace(/<table/g, '<table class="m-view"')
this.markdown = this.markdown
.replace(/<table/g, () => {
const uniqueId = `table-${this.tableIdCounter++}`
return `<table contenteditable='false' id="${uniqueId}" class="m-view"`
})
.replace(/<script/g, '< script')
this.markdownHtml = this.md.render(this.markdown.replace(/class="m-view"/g, ''))
},
// 向 iframe 发送消息
sendMessageToIframe(type, message) {
@@ -197,8 +246,6 @@ export default {
this.getPDFDetailBbox()
this.getPDFDetailMarkDown()
this.prdUrl = getPdfUrl({ documentId: this.documentId })
console.log(this.prdUrl)
},
mounted() {
// 监听 iframe 的 postMessage 事件