[前端+RAG] 修复:异步上传+MySQL回写导读;PDF切换detached(Uint8Array复制);对话工具栏遮挡;阅读模式空白

This commit is contained in:
2026-04-02 14:59:17 +08:00
parent 8b7e3a726b
commit 05e33d1d05
4 changed files with 120 additions and 62 deletions

View File

@@ -74,9 +74,17 @@ const loadPdf = async () => {
loading.value = true;
error.value = '';
try {
// 每次加载都复制一份,避免 pdfjs worker transfer 后 detach 原始数据
const rawSrc = toRaw(props.src);
const data = rawSrc instanceof ArrayBuffer ? new Uint8Array(rawSrc) : rawSrc;
const loadingTask = pdfjsLib.getDocument({ data });
let bytes: Uint8Array;
if (rawSrc instanceof Uint8Array) {
bytes = new Uint8Array(rawSrc); // 复制
} else if (rawSrc instanceof ArrayBuffer) {
bytes = new Uint8Array(new Uint8Array(rawSrc)); // 复制
} else {
bytes = rawSrc as any;
}
const loadingTask = pdfjsLib.getDocument({ data: bytes });
pdfDoc = await loadingTask.promise;
const numPages = pdfDoc.numPages;
pages.value = Array.from({ length: numPages }, (_, i) => i + 1);

View File

@@ -434,7 +434,7 @@ const handleStop = async () => {
<style lang="less" scoped>
.message-content {
height: calc(100% - 255px);
height: calc(100% - 290px);
overflow-y: auto;
padding: 20px;
@@ -456,12 +456,9 @@ const handleStop = async () => {
.tool-bar {
display: flex;
justify-content: space-between;
width: calc(100% - 15px);
padding-top: 30px;
height: 65px;
position:absolute;
bottom:275px;
background: linear-gradient( 360deg, #C0D4FD 0%, rgba(199,219,255,0) 100%);
width: 100%;
padding-top: 8px;
height: 40px;
.label {
display: flex;
justify-content: space-around;

View File

@@ -110,7 +110,7 @@
</div>
<!-- PDF 原生渲染 -->
<div v-if="fileType === 'pdf' && !readingMode" class="file-content" ref="fileContent" id="file-content">
<PdfViewer v-if="pdfData" :src="pdfData" :scale="1.3" />
<PdfViewer v-if="pdfBytes" :src="pdfBytes" :scale="1.3" />
</div>
<!-- HTML 阅读模式PDF 阅读模式 + 非PDF文件 -->
<div v-else class="file-content" ref="fileContent" id="file-content">
@@ -284,13 +284,6 @@ const docHtml = ref('');
const fileContent = ref(null);
const readingBox = ref(null);
const pdfBytes = ref<Uint8Array | null>(null); // 存原始字节,不会被 detach
const pdfData = computed(() => {
// 每次访问时复制一份新的 ArrayBuffer 给 PdfViewer
if (!pdfBytes.value) return null;
const copy = new ArrayBuffer(pdfBytes.value.byteLength);
new Uint8Array(copy).set(pdfBytes.value);
return copy;
});
const readingMode = ref(false);
const fileType = computed(() => {
const name = selectedFile.value?.fileName || '';
@@ -915,8 +908,12 @@ onMounted(async () => {
.view-md {
padding: 20px;
// 覆盖 PyMuPDF get_text("html") 输出的固定宽度
:deep(div[style*="width:"]) { width: 100% !important; max-width: 100% !important; }
:deep(.pdf-page > div) { width: 100% !important; }
:deep(div) { max-width: 100% !important; }
:deep(div[style*="width:"]) { width: auto !important; max-width: 100% !important; }
:deep(.pdf-page) { max-width: 100% !important; }
:deep(.pdf-page > div) { width: auto !important; max-width: 100% !important; }
:deep(.pdf-preview) { max-width: 100% !important; }
:deep(section) { max-width: 100% !important; }
:deep(p) { font-size: 15px; line-height: 1.8rem; margin-block-start: 0; }
:deep(.highlight) { background: #D0EAC8; }
:deep(.note-flag) { width: 23px; height: 28px; line-height: 28px; display: inline-block; text-align: center; font-weight: bold; font-size: 10px; margin-left: 8px; cursor: pointer; background: url("@/assets/images/reading/note.png"); color: #004EA0; background-size: contain !important; background-repeat: no-repeat !important; background-position: center bottom !important; }