feat(docx-preview): 集成DOCX文件预览功能组件
Some checks failed
Lint Code / Lint Code (push) Failing after 4m20s
Some checks failed
Lint Code / Lint Code (push) Failing after 4m20s
- 新增ReDocxPreview组件,实现基于docx-preview库的DOCX文件渲染 - 实现DOCX文件加载、错误处理及打印功能 - 知识库视图增加对DOCX文件预览支持与对应UI样式调整 - 更新本地中英文菜单配置,添加"pureDocx"菜单项 - 增加docx-preview依赖及相关包锁信息 - 优化风险评估和工单管理视图的页面内边距样式
This commit is contained in:
@@ -187,6 +187,7 @@ menus:
|
||||
pureSwiper: Swiper Plugin
|
||||
pureVirtualList: Virtual List
|
||||
purePdf: PDF Preview
|
||||
pureDocx: DOCX Preview
|
||||
pureExcel: Export Excel
|
||||
pureInfiniteScroll: Table Infinite Scroll
|
||||
pureSensitive: Sensitive Filter
|
||||
|
||||
@@ -187,6 +187,7 @@ menus:
|
||||
pureSwiper: Swiper插件
|
||||
pureVirtualList: 虚拟列表
|
||||
purePdf: PDF预览
|
||||
pureDocx: DOCX预览
|
||||
pureExcel: 导出Excel
|
||||
pureInfiniteScroll: 表格无限滚动
|
||||
pureSensitive: 敏感词过滤
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
"cropperjs": "^1.6.2",
|
||||
"dayjs": "^1.11.20",
|
||||
"deep-chat": "^2.4.2",
|
||||
"docx-preview": "^0.3.7",
|
||||
"echarts": "^6.0.0",
|
||||
"el-table-infinite-scroll": "^3.0.8",
|
||||
"element-plus": "^2.13.6",
|
||||
|
||||
72
pnpm-lock.yaml
generated
72
pnpm-lock.yaml
generated
@@ -77,6 +77,9 @@ importers:
|
||||
deep-chat:
|
||||
specifier: ^2.4.2
|
||||
version: 2.4.2
|
||||
docx-preview:
|
||||
specifier: ^0.3.7
|
||||
version: 0.3.7
|
||||
echarts:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
@@ -2919,6 +2922,9 @@ packages:
|
||||
core-js@3.49.0:
|
||||
resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==}
|
||||
|
||||
core-util-is@1.0.3:
|
||||
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
||||
|
||||
cosmiconfig-typescript-loader@6.2.0:
|
||||
resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==}
|
||||
engines: {node: '>=v18'}
|
||||
@@ -3136,6 +3142,9 @@ packages:
|
||||
dijkstrajs@1.0.3:
|
||||
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
|
||||
|
||||
docx-preview@0.3.7:
|
||||
resolution: {integrity: sha512-Lav69CTA/IYZPJTsKH7oYeoZjyg96N0wEJMNslGJnZJ+dMUZK85Lt5ASC79yUlD48ecWjuv+rkcmFt6EVPV0Xg==}
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
|
||||
|
||||
@@ -3843,6 +3852,9 @@ packages:
|
||||
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
isarray@1.0.0:
|
||||
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||
|
||||
isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
@@ -4073,6 +4085,9 @@ packages:
|
||||
jsonfile@6.2.0:
|
||||
resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==}
|
||||
|
||||
jszip@3.10.1:
|
||||
resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
|
||||
|
||||
keyv@4.5.4:
|
||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||
|
||||
@@ -4115,6 +4130,9 @@ packages:
|
||||
lie@3.1.1:
|
||||
resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==}
|
||||
|
||||
lie@3.3.0:
|
||||
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
|
||||
|
||||
lightningcss-android-arm64@1.32.0:
|
||||
resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
@@ -4523,6 +4541,9 @@ packages:
|
||||
package-manager-detector@1.6.0:
|
||||
resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==}
|
||||
|
||||
pako@1.0.11:
|
||||
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
|
||||
|
||||
parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -4925,6 +4946,9 @@ packages:
|
||||
react-is@17.0.2:
|
||||
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
||||
|
||||
readable-stream@2.3.8:
|
||||
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
|
||||
|
||||
readable-stream@3.6.2:
|
||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||
engines: {node: '>= 6'}
|
||||
@@ -5038,6 +5062,9 @@ packages:
|
||||
run-parallel@1.2.0:
|
||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||
|
||||
safe-buffer@5.1.2:
|
||||
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
|
||||
|
||||
safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
|
||||
@@ -5075,6 +5102,9 @@ packages:
|
||||
set-blocking@2.0.0:
|
||||
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
|
||||
|
||||
setimmediate@1.0.5:
|
||||
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -5213,6 +5243,9 @@ packages:
|
||||
resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
string_decoder@1.1.1:
|
||||
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
|
||||
|
||||
string_decoder@1.3.0:
|
||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||
|
||||
@@ -8521,6 +8554,8 @@ snapshots:
|
||||
|
||||
core-js@3.49.0: {}
|
||||
|
||||
core-util-is@1.0.3: {}
|
||||
|
||||
cosmiconfig-typescript-loader@6.2.0(@types/node@20.19.37)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@types/node': 20.19.37
|
||||
@@ -8737,6 +8772,10 @@ snapshots:
|
||||
|
||||
dijkstrajs@1.0.3: {}
|
||||
|
||||
docx-preview@0.3.7:
|
||||
dependencies:
|
||||
jszip: 3.10.1
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
@@ -9542,6 +9581,8 @@ snapshots:
|
||||
dependencies:
|
||||
is-docker: 2.2.1
|
||||
|
||||
isarray@1.0.0: {}
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
istanbul-lib-coverage@3.2.2: {}
|
||||
@@ -10014,6 +10055,13 @@ snapshots:
|
||||
optionalDependencies:
|
||||
graceful-fs: 4.2.11
|
||||
|
||||
jszip@3.10.1:
|
||||
dependencies:
|
||||
lie: 3.3.0
|
||||
pako: 1.0.11
|
||||
readable-stream: 2.3.8
|
||||
setimmediate: 1.0.5
|
||||
|
||||
keyv@4.5.4:
|
||||
dependencies:
|
||||
json-buffer: 3.0.1
|
||||
@@ -10052,6 +10100,10 @@ snapshots:
|
||||
dependencies:
|
||||
immediate: 3.0.6
|
||||
|
||||
lie@3.3.0:
|
||||
dependencies:
|
||||
immediate: 3.0.6
|
||||
|
||||
lightningcss-android-arm64@1.32.0:
|
||||
optional: true
|
||||
|
||||
@@ -10427,6 +10479,8 @@ snapshots:
|
||||
|
||||
package-manager-detector@1.6.0: {}
|
||||
|
||||
pako@1.0.11: {}
|
||||
|
||||
parent-module@1.0.1:
|
||||
dependencies:
|
||||
callsites: 3.1.0
|
||||
@@ -10793,6 +10847,16 @@ snapshots:
|
||||
|
||||
react-is@17.0.2: {}
|
||||
|
||||
readable-stream@2.3.8:
|
||||
dependencies:
|
||||
core-util-is: 1.0.3
|
||||
inherits: 2.0.4
|
||||
isarray: 1.0.0
|
||||
process-nextick-args: 2.0.1
|
||||
safe-buffer: 5.1.2
|
||||
string_decoder: 1.1.1
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
readable-stream@3.6.2:
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
@@ -10930,6 +10994,8 @@ snapshots:
|
||||
dependencies:
|
||||
queue-microtask: 1.2.3
|
||||
|
||||
safe-buffer@5.1.2: {}
|
||||
|
||||
safe-buffer@5.2.1: {}
|
||||
|
||||
safer-buffer@2.1.2: {}
|
||||
@@ -10960,6 +11026,8 @@ snapshots:
|
||||
|
||||
set-blocking@2.0.0: {}
|
||||
|
||||
setimmediate@1.0.5: {}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
dependencies:
|
||||
shebang-regex: 3.0.0
|
||||
@@ -11096,6 +11164,10 @@ snapshots:
|
||||
get-east-asian-width: 1.5.0
|
||||
strip-ansi: 7.2.0
|
||||
|
||||
string_decoder@1.1.1:
|
||||
dependencies:
|
||||
safe-buffer: 5.1.2
|
||||
|
||||
string_decoder@1.3.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
172
src/components/ReDocxPreview/index.vue
Normal file
172
src/components/ReDocxPreview/index.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, onMounted, nextTick } from "vue";
|
||||
import { renderAsync } from "docx-preview";
|
||||
|
||||
defineOptions({
|
||||
name: "ReDocxPreview"
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
url?: string;
|
||||
file?: File | Blob;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "rendered"): void;
|
||||
(e: "error", error: Error): void;
|
||||
}>();
|
||||
|
||||
const docxContainerRef = ref<HTMLDivElement>();
|
||||
const loading = ref(true);
|
||||
const errorMsg = ref("");
|
||||
|
||||
// 渲染 docx 文件
|
||||
async function renderDocx() {
|
||||
if (!docxContainerRef.value) return;
|
||||
|
||||
loading.value = true;
|
||||
errorMsg.value = "";
|
||||
|
||||
try {
|
||||
// 清空之前的内容
|
||||
docxContainerRef.value.innerHTML = "";
|
||||
|
||||
let arrayBuffer: ArrayBuffer;
|
||||
|
||||
if (props.file) {
|
||||
// 如果传入的是 File 或 Blob
|
||||
arrayBuffer = await props.file.arrayBuffer();
|
||||
} else if (props.url) {
|
||||
// 从 URL 获取文件
|
||||
const response = await fetch(props.url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`加载文件失败: ${response.status}`);
|
||||
}
|
||||
arrayBuffer = await response.arrayBuffer();
|
||||
} else {
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用 docx-preview 渲染
|
||||
await renderAsync(arrayBuffer, docxContainerRef.value, undefined, {
|
||||
className: "docx-container",
|
||||
inWrapper: true,
|
||||
ignoreWidth: false,
|
||||
ignoreHeight: false,
|
||||
ignoreFonts: false,
|
||||
breakPages: true,
|
||||
ignoreLastRenderedPageBreak: true,
|
||||
experimental: false,
|
||||
trimXmlDeclaration: true,
|
||||
useBase64URL: true,
|
||||
renderHeaders: true,
|
||||
renderFooters: true,
|
||||
renderFootnotes: true,
|
||||
renderEndnotes: true
|
||||
});
|
||||
|
||||
emit("rendered");
|
||||
} catch (error: any) {
|
||||
console.error("渲染 docx 文件失败:", error);
|
||||
errorMsg.value = error.message || "渲染 docx 文件失败";
|
||||
emit("error", error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 打印文档
|
||||
function handlePrint() {
|
||||
if (!docxContainerRef.value) return;
|
||||
const printContent = docxContainerRef.value.innerHTML;
|
||||
const printWindow = window.open("", "_blank");
|
||||
if (printWindow) {
|
||||
printWindow.document.write(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>打印文档</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 20px; }
|
||||
.docx-wrapper { background: white; }
|
||||
@page { margin: 1cm; }
|
||||
</style>
|
||||
</head>
|
||||
<body>${printContent}</body>
|
||||
</html>
|
||||
`);
|
||||
printWindow.document.close();
|
||||
printWindow.print();
|
||||
}
|
||||
}
|
||||
|
||||
// 暴露方法供父组件调用
|
||||
defineExpose({
|
||||
refresh: renderDocx,
|
||||
print: handlePrint
|
||||
});
|
||||
|
||||
// 监听 URL 或文件变化
|
||||
watch(
|
||||
() => [props.url, props.file],
|
||||
() => {
|
||||
nextTick(() => {
|
||||
renderDocx();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
renderDocx();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="docx-preview-component">
|
||||
<div v-if="errorMsg" class="docx-error">
|
||||
<el-empty :description="errorMsg">
|
||||
<el-button type="primary" @click="renderDocx">重新加载</el-button>
|
||||
</el-empty>
|
||||
</div>
|
||||
<div v-else v-loading="loading" class="docx-loading-wrapper">
|
||||
<div ref="docxContainerRef" class="docx-render-container" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.docx-preview-component {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.docx-error {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.docx-loading-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.docx-render-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
:deep(.docx-wrapper) {
|
||||
padding: 20px;
|
||||
background: white;
|
||||
|
||||
section.docx {
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 0 8px rgb(0 0 0 / 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -3,6 +3,7 @@ import { ref, onMounted, watch } from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import VuePdfEmbed from "vue-pdf-embed";
|
||||
import ReDocxPreview from "@/components/ReDocxPreview/index.vue";
|
||||
import {
|
||||
getDocuments,
|
||||
uploadDocument,
|
||||
@@ -63,6 +64,7 @@ const previewRotation = ref(0);
|
||||
const previewPdfRef = ref<any>(null);
|
||||
const previewAllPages = ref(false);
|
||||
const previewRotations = [0, 90, 180, 270];
|
||||
const previewDocxRef = ref<InstanceType<typeof ReDocxPreview> | null>(null);
|
||||
|
||||
// 加载项目列表
|
||||
async function loadProjects() {
|
||||
@@ -734,7 +736,52 @@ onMounted(() => {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Word/其他文件 - 使用iframe尝试预览 -->
|
||||
<!-- Word预览 -->
|
||||
<template
|
||||
v-else-if="
|
||||
['doc', 'docx'].includes(previewDoc.fileType?.toLowerCase())
|
||||
"
|
||||
>
|
||||
<div class="docx-preview-container">
|
||||
<div class="docx-toolbar">
|
||||
<div class="docx-title">
|
||||
{{ previewDoc.title }}
|
||||
</div>
|
||||
<div class="docx-actions">
|
||||
<el-button link @click="previewDocxRef?.refresh()">
|
||||
<component
|
||||
:is="useRenderIcon('ri/refresh-line')"
|
||||
:size="18"
|
||||
/>
|
||||
刷新
|
||||
</el-button>
|
||||
<el-button link @click="previewDocxRef?.print()">
|
||||
<component
|
||||
:is="useRenderIcon('ri/printer-line')"
|
||||
:size="18"
|
||||
/>
|
||||
打印
|
||||
</el-button>
|
||||
<el-button link @click="handleOpenFile(previewDoc.fileUrl)">
|
||||
<component
|
||||
:is="useRenderIcon('ri/download-line')"
|
||||
:size="18"
|
||||
/>
|
||||
下载
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-scrollbar class="docx-scrollbar">
|
||||
<ReDocxPreview
|
||||
ref="previewDocxRef"
|
||||
:url="previewDoc.fileUrl"
|
||||
class="docx-viewer"
|
||||
/>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 其他文件类型 -->
|
||||
<template v-else>
|
||||
<div class="other-preview-container">
|
||||
<div class="preview-tip">
|
||||
@@ -887,6 +934,43 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// DOCX预览样式
|
||||
.docx-preview-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 70vh;
|
||||
|
||||
.docx-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px 0;
|
||||
margin-bottom: 8px;
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
|
||||
.docx-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.docx-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.docx-scrollbar {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.docx-viewer {
|
||||
width: 100%;
|
||||
min-height: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
// 其他文件预览样式
|
||||
.other-preview-container {
|
||||
display: flex;
|
||||
|
||||
@@ -888,7 +888,7 @@ onUnmounted(() => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.risk-assessment {
|
||||
padding: 16px;
|
||||
padding: 16px 80px 16px 16px;
|
||||
|
||||
.stat-card {
|
||||
.stat-icon {
|
||||
|
||||
@@ -805,7 +805,7 @@ onMounted(() => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.workorder-management {
|
||||
padding: 16px;
|
||||
padding: 16px 80px 16px 16px;
|
||||
|
||||
.stat-card {
|
||||
.stat-icon {
|
||||
|
||||
Reference in New Issue
Block a user