feat(RenderMinerU): 实现 MD 文件加载及分页功能- 新增 getMd_info 和 mdIndex 函数,用于获取 MD 文件信息和内容

- 实现 MD 文件内容的渲染和分页滚动
- 优化编辑模式下的 Markdown 处理
- 去除无用的 console.log 语句
- 调整样式,隐藏滚动条
This commit is contained in:
陈昱达
2025-04-21 15:35:25 +08:00
parent 97ebe1926d
commit 22716957f2
5 changed files with 141 additions and 20 deletions

View File

@@ -268,3 +268,21 @@ export function imageRetry(data) {
noLoading: true noLoading: true
}) })
} }
export function getMd_info(params) {
return request({
url: getUrl(`/document/mineru/md_info`),
method: 'get',
params,
noLoading: true
})
}
export function mdIndex(params) {
return request({
url: getUrl(`/document/mineru/md`),
method: 'get',
params,
noLoading: true,
back: true
})
}

View File

@@ -53,6 +53,9 @@ service.interceptors.response.use(
const res = response.data const res = response.data
endLoading() endLoading()
if (response.config.back) {
return response.data
}
// 检查res.content是否存在处理blob等特殊响应类型 // 检查res.content是否存在处理blob等特殊响应类型
if (res.content) { if (res.content) {
if (res.content.code) { if (res.content.code) {

View File

@@ -395,3 +395,9 @@ body .el-collapse-item__wrap {
.public-icon + .public-icon { .public-icon + .public-icon {
margin-left: 10px; margin-left: 10px;
} }
//去除滚动条
.view-body::-webkit-scrollbar {
width: 0px;
height: 0px;
}

View File

@@ -15,12 +15,26 @@
class="miner-u el-card is-always-shadow ml20" class="miner-u el-card is-always-shadow ml20"
></iframe> ></iframe>
<div style="flex:1;" class="mh20 miner-u-md" v-loading="finishedMiner" element-loading-text="正在识别中..."> <div style="flex:1;" class="mh20 miner-u-md" v-loading="finishedMiner" element-loading-text="正在识别中...">
<el-tabs type="border-card" style="height: 100%;overflow: hidden" @tab-click="changeTab"> <el-tabs type="border-card" style="height: 100%;overflow: hidden" @tab-click="changeTab" v-model="tab">
<el-tab-pane label="预览" style="overflow:scroll;"> <el-tab-pane label="预览" style="overflow:scroll;" ref="scrollView" name="0">
<div v-html="markdownHtml" class="view-body" id="viewBody" ref="viewBody"></div> <div
v-html="markdownHtml"
class="view-body"
id="viewBody"
ref="viewBody"
style="height:calc(100vh - 230px);overflow-y: scroll;overflow-x:hidden "
></div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="编辑" :disabled="!isEdit" v-if="isEdit"> <el-tab-pane label="编辑" :disabled="!isEdit" v-if="isEdit" name="1">
<div class="lineH25 view-body" contenteditable id="md-editor" @blur="emitMarkDown" v-html="markdown"></div> <div
class="lineH25 view-body"
contenteditable
id="md-editor"
ref="mdEditor"
@blur="emitMarkDown"
v-html="markdown"
style="height:calc(100vh - 230px);overflow-y: scroll;overflow-x:hidden "
></div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@@ -28,7 +42,17 @@
</div> </div>
</template> </template>
<script> <script>
import { getPdfUrl, minerUBbox, minerUMarkDown, minerUMarkDownUpdate, minerURetry, minerUQuery, imageRetry } from '@/api/generatedApi/index' import {
getPdfUrl,
minerUBbox,
minerUMarkDown,
minerUMarkDownUpdate,
minerURetry,
minerUQuery,
imageRetry,
getMd_info,
mdIndex
} from '@/api/generatedApi/index'
import { DEFAULT_COLOR_SECTION, PDF_COLOR_PICKER } from './pdf-color' import { DEFAULT_COLOR_SECTION, PDF_COLOR_PICKER } from './pdf-color'
import MarkdownIt from 'markdown-it' import MarkdownIt from 'markdown-it'
import markdownItKatex from 'markdown-it-katex' import markdownItKatex from 'markdown-it-katex'
@@ -40,6 +64,8 @@ export default {
name: 'index', name: 'index',
data() { data() {
return { return {
tab: '0',
mdPges: 0,
tableIdCounter: 0, tableIdCounter: 0,
finishedMiner: false, finishedMiner: false,
prdUrl: ``, prdUrl: ``,
@@ -59,7 +85,6 @@ export default {
icon: 'el-icon-view', icon: 'el-icon-view',
name: 'retry', name: 'retry',
click: tableElement => { click: tableElement => {
console.log('重新识别')
// 获取的 识别图片 // 获取的 识别图片
this.selectionImagePath = '' this.selectionImagePath = ''
let chooseItem = this.findMatchingTable(tableElement) let chooseItem = this.findMatchingTable(tableElement)
@@ -159,16 +184,38 @@ export default {
if (newVal) { if (newVal) {
this.getMinerUStatus() this.getMinerUStatus()
this.prdUrl = getPdfUrl({ documentId: newVal }) this.prdUrl = getPdfUrl({ documentId: newVal })
console.log('this.prdUrl')
} }
}, },
immediate: true immediate: true
},
page: {
handler(newVal, oldVal) {
if (newVal) {
this.changePage(newVal, this.tab)
}
}
} }
}, },
components: {}, components: {},
filters: {}, filters: {},
methods: { methods: {
// //changePage
changePage(page) {
let documentId = document.getElementById(`view-code-${page - 1}`)
let viewBody = document.getElementById('viewBody')
if (this.tab === '1') {
documentId = document.getElementById(`ebiz-code-${page - 1}`)
viewBody = document.getElementById('md-editor')
}
if (documentId) {
viewBody.scrollTo({
top: documentId.offsetTop - 16,
behavior: 'smooth'
})
}
},
//重新识别
retryMinerImage(chooseItem, loading, tableElement) { retryMinerImage(chooseItem, loading, tableElement) {
imageRetry({ imageRetry({
documentId: this.documentId, documentId: this.documentId,
@@ -316,7 +363,6 @@ export default {
linesMap(table) { linesMap(table) {
;(table.blocks ? table.blocks : []).map(lines => { ;(table.blocks ? table.blocks : []).map(lines => {
console.log(lines)
lines.lines.map(spans => { lines.lines.map(spans => {
spans.spans.map(span => { spans.spans.map(span => {
this.selectionTable.push({ html: span.html, image_path: span.image_path }) this.selectionTable.push({ html: span.html, image_path: span.image_path })
@@ -350,7 +396,10 @@ export default {
this.$emit('getMarkDownIt', { innerText: pre }) this.$emit('getMarkDownIt', { innerText: pre })
}, },
saveMarkDown() { saveMarkDown() {
let pre = document.getElementById('md-editor').innerText let pre = document.getElementById('md-editor').innerHTML
// pre + ebiz-code标签
minerUMarkDownUpdate({ minerUMarkDownUpdate({
documentId: this.documentId, documentId: this.documentId,
newMd: pre newMd: pre
@@ -395,32 +444,77 @@ export default {
this.bboxList = this.formatJson(JSON.parse(JSON.stringify(res.content.content))) this.bboxList = this.formatJson(JSON.parse(JSON.stringify(res.content.content)))
this.setTableSelection(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 重新刷新iframe
this.$refs.iframe.contentWindow.location.reload() this.$refs.iframe.contentWindow.location.reload()
this.getPDFDetailMarkDown() this.getMdPage()
}) })
}, },
changeTab() {
let pre = document.getElementById('md-editor').innerHTML getMdPage() {
let responseText = ''
getMd_info({ documentId: this.documentId }).then(async res => {
if (res) {
this.mdPges = res.content.content.indexList
for (let i = 0; i < this.mdPges.length; i++) {
let text = await mdIndex({ index: i, documentId: this.documentId })
responseText += `<ebiz-code id='ebiz-code-${i}'></ebiz-code>
${text}`
}
this.getPDFDetailMarkDown(responseText)
}
})
},
changeTab(evt) {
let editor = document.getElementById('md-editor')
// pre 获取 table的html 给table 增加 对照表的path id
let pre = editor.innerHTML
let tables = editor.querySelectorAll('table')
if (tables) {
tables.forEach(item => {
let pathId = item.getAttribute('data-path-id')
if (!pathId) {
let ite = this.findMatchingTable(item)
if (ite) {
item.setAttribute('data-path-id', ite.image_path.replace(/\.[^/.]+$/, ''))
item.setAttribute('data-path-type', ite.image_path.match(/\.[^/.]+$/)[0])
}
}
})
}
// pre = JSON.stringify(pre) // pre = JSON.stringify(pre)
// let copyMdHtml = md.render(pre) // let copyMdHtml = md.render(pre)
// 给 copyMdHtml 里面的table 增加 class m-view // 给 copyMdHtml 里面的table 增加 class m-view
// copyMdHtml = copyMdHtml.re // copyMdHtml = copyMdHtml.re
this.markdownHtml = md.render(pre.replace(/class="m-view"/g, '')) this.markdownHtml = md.render(pre.replace(/class="m-view"/g, '').replace(/ebiz-code/g, 'view-code'))
setTimeout(() => {
this.changePage(this.page, evt)
}, 1000)
}, },
// 初始md 文档 // 初始md 文档
async getPDFDetailMarkDown() { async getPDFDetailMarkDown(responseText) {
// responseText 判断是否包含ebiz-code
const response = await fetch(minerUMarkDown({ documentId: this.documentId })) const response = await fetch(minerUMarkDown({ documentId: this.documentId }))
this.markdown = await response.text() this.markdown = await response.text()
// this.markdown 包含 ebiz-code
if (this.markdown.indexOf('<ebiz-code ') < 0) {
this.markdown = responseText
}
this.markdown = this.markdown this.markdown = this.markdown
.replace(/<table/g, () => { .replace(/<table/g, () => {
const uniqueId = `table-${this.tableIdCounter++}` const uniqueId = `table-${this.tableIdCounter++}`
return `<table contenteditable='false' class="m-view"` return `<table contenteditable='false' class="m-view"`
}) })
.replace(/<script/g, '< script') .replace(/<script/g, '< script')
this.markdownHtml = this.md.render(this.markdown.replace(/class="m-view"/g, ''))
let text = this.markdown
this.markdownHtml = this.md.render(this.markdown.replace(/class="m-view"/g, '').replace(/ebiz-code/g, 'view-code'))
}, },
// 向 iframe 发送消息 // 向 iframe 发送消息
sendMessageToIframe(type, message) { sendMessageToIframe(type, message) {

View File

@@ -54,7 +54,7 @@ export default {
return { return {
visible: false, visible: false,
active: 0, active: 0,
documentId: '1362161577009188864' documentId: '1363864715567140864'
} }
}, },
props: {}, props: {},