feat: 完善知识库、策略预览与OnlyOffice集成,增强后端启动依赖检查
This commit is contained in:
@@ -90,6 +90,10 @@ fi
|
|||||||
ENV_OVERRIDE_SERVER_HOST_SET=false
|
ENV_OVERRIDE_SERVER_HOST_SET=false
|
||||||
ENV_OVERRIDE_POSTGRES_HOST_SET=false
|
ENV_OVERRIDE_POSTGRES_HOST_SET=false
|
||||||
ENV_OVERRIDE_DATABASE_URL_SET=false
|
ENV_OVERRIDE_DATABASE_URL_SET=false
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_ENABLED_SET=false
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL_SET=false
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL_SET=false
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET_SET=false
|
||||||
|
|
||||||
if [ "${SERVER_HOST+x}" = x ]; then
|
if [ "${SERVER_HOST+x}" = x ]; then
|
||||||
ENV_OVERRIDE_SERVER_HOST_SET=true
|
ENV_OVERRIDE_SERVER_HOST_SET=true
|
||||||
@@ -106,6 +110,26 @@ if [ "${DATABASE_URL+x}" = x ]; then
|
|||||||
ENV_OVERRIDE_DATABASE_URL="$DATABASE_URL"
|
ENV_OVERRIDE_DATABASE_URL="$DATABASE_URL"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${ONLYOFFICE_ENABLED+x}" = x ]; then
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_ENABLED_SET=true
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_ENABLED="$ONLYOFFICE_ENABLED"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${ONLYOFFICE_PUBLIC_URL+x}" = x ]; then
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL_SET=true
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL="$ONLYOFFICE_PUBLIC_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${ONLYOFFICE_BACKEND_URL+x}" = x ]; then
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL_SET=true
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL="$ONLYOFFICE_BACKEND_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${ONLYOFFICE_JWT_SECRET+x}" = x ]; then
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET_SET=true
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET="$ONLYOFFICE_JWT_SECRET"
|
||||||
|
fi
|
||||||
|
|
||||||
set -a
|
set -a
|
||||||
. "$ROOT_ENV_FILE"
|
. "$ROOT_ENV_FILE"
|
||||||
set +a
|
set +a
|
||||||
@@ -122,6 +146,22 @@ if [ "$ENV_OVERRIDE_DATABASE_URL_SET" = true ]; then
|
|||||||
DATABASE_URL="$ENV_OVERRIDE_DATABASE_URL"
|
DATABASE_URL="$ENV_OVERRIDE_DATABASE_URL"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$ENV_OVERRIDE_ONLYOFFICE_ENABLED_SET" = true ]; then
|
||||||
|
ONLYOFFICE_ENABLED="$ENV_OVERRIDE_ONLYOFFICE_ENABLED"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL_SET" = true ]; then
|
||||||
|
ONLYOFFICE_PUBLIC_URL="$ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL_SET" = true ]; then
|
||||||
|
ONLYOFFICE_BACKEND_URL="$ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET_SET" = true ]; then
|
||||||
|
ONLYOFFICE_JWT_SECRET="$ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET"
|
||||||
|
fi
|
||||||
|
|
||||||
SERVER_HOST="${SERVER_HOST:-0.0.0.0}"
|
SERVER_HOST="${SERVER_HOST:-0.0.0.0}"
|
||||||
SERVER_PORT="${SERVER_PORT:-8000}"
|
SERVER_PORT="${SERVER_PORT:-8000}"
|
||||||
DEFAULT_SERVER_RELOAD="false"
|
DEFAULT_SERVER_RELOAD="false"
|
||||||
@@ -189,7 +229,7 @@ run_bootstrap_python() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies_ready() {
|
dependencies_ready() {
|
||||||
"$PYTHON_BIN" -c "import fastapi, uvicorn, sqlalchemy, alembic, pydantic_settings" >/dev/null 2>&1
|
"$PYTHON_BIN" -c "import alembic, dotenv, email_validator, fastapi, jwt, psycopg, pydantic_settings, sqlalchemy, uvicorn" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
pip_ready() {
|
pip_ready() {
|
||||||
|
|||||||
@@ -2,16 +2,16 @@
|
|||||||
"version": 1,
|
"version": 1,
|
||||||
"documents": [
|
"documents": [
|
||||||
{
|
{
|
||||||
"id": "fde293670eac4ae2b90a80eeb9f27b5b",
|
"id": "8af9350f0e02488aaf0df2001286b764",
|
||||||
"folder": "财务知识库",
|
"folder": "财务知识库",
|
||||||
"original_name": "差旅费季度报销258878.xlsx",
|
"original_name": "差旅费季度报销258878.xlsx",
|
||||||
"stored_name": "fde293670eac4ae2b90a80eeb9f27b5b__差旅费季度报销258878.xlsx",
|
"stored_name": "8af9350f0e02488aaf0df2001286b764__差旅费季度报销258878.xlsx",
|
||||||
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
"extension": "xlsx",
|
"extension": "xlsx",
|
||||||
"size_bytes": 11123,
|
"size_bytes": 11123,
|
||||||
"sha256": "ea02e59d3a22a4a02284172acce3fd4c6367a26f1a4fd196dc4f65afed1bd4c5",
|
"sha256": "ea02e59d3a22a4a02284172acce3fd4c6367a26f1a4fd196dc4f65afed1bd4c5",
|
||||||
"created_at": "2026-05-09T03:33:44.101489+00:00",
|
"created_at": "2026-05-09T05:46:24.699125+00:00",
|
||||||
"updated_at": "2026-05-09T03:33:44.101489+00:00",
|
"updated_at": "2026-05-09T05:46:24.699125+00:00",
|
||||||
"uploaded_by": "admin",
|
"uploaded_by": "admin",
|
||||||
"version_number": 1
|
"version_number": 1
|
||||||
}
|
}
|
||||||
|
|||||||
40
server/tests/test_server_start_dependencies.py
Normal file
40
server/tests/test_server_start_dependencies.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
import stat
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def test_dependencies_ready_fails_when_jwt_is_missing(tmp_path: Path) -> None:
|
||||||
|
fake_python = tmp_path / "fake-python.sh"
|
||||||
|
fake_python.write_text(
|
||||||
|
"""#!/usr/bin/env bash
|
||||||
|
if [ "$1" = "-c" ]; then
|
||||||
|
case "$2" in
|
||||||
|
*jwt*) exit 1 ;;
|
||||||
|
*) exit 0 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
""",
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
fake_python.chmod(fake_python.stat().st_mode | stat.S_IEXEC)
|
||||||
|
|
||||||
|
script_path = Path(__file__).resolve().parents[1] / "server_start.sh"
|
||||||
|
script_prefix = script_path.read_text(encoding="utf-8").split('case "$MODE" in', 1)[0]
|
||||||
|
command = f"""{script_prefix}
|
||||||
|
PYTHON_BIN="{fake_python}"
|
||||||
|
dependencies_ready
|
||||||
|
"""
|
||||||
|
result = subprocess.run(
|
||||||
|
["bash", "-c", command],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
env={**os.environ, "MODE": "test"},
|
||||||
|
cwd=script_path.parent,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.returncode != 0
|
||||||
40
start.sh
40
start.sh
@@ -38,6 +38,10 @@ fi
|
|||||||
|
|
||||||
ENV_OVERRIDE_WEB_HOST_SET=false
|
ENV_OVERRIDE_WEB_HOST_SET=false
|
||||||
ENV_OVERRIDE_SERVER_HOST_SET=false
|
ENV_OVERRIDE_SERVER_HOST_SET=false
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_ENABLED_SET=false
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL_SET=false
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL_SET=false
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET_SET=false
|
||||||
|
|
||||||
if [ "${WEB_HOST+x}" = x ]; then
|
if [ "${WEB_HOST+x}" = x ]; then
|
||||||
ENV_OVERRIDE_WEB_HOST_SET=true
|
ENV_OVERRIDE_WEB_HOST_SET=true
|
||||||
@@ -49,6 +53,26 @@ if [ "${SERVER_HOST+x}" = x ]; then
|
|||||||
ENV_OVERRIDE_SERVER_HOST="$SERVER_HOST"
|
ENV_OVERRIDE_SERVER_HOST="$SERVER_HOST"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${ONLYOFFICE_ENABLED+x}" = x ]; then
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_ENABLED_SET=true
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_ENABLED="$ONLYOFFICE_ENABLED"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${ONLYOFFICE_PUBLIC_URL+x}" = x ]; then
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL_SET=true
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL="$ONLYOFFICE_PUBLIC_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${ONLYOFFICE_BACKEND_URL+x}" = x ]; then
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL_SET=true
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL="$ONLYOFFICE_BACKEND_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${ONLYOFFICE_JWT_SECRET+x}" = x ]; then
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET_SET=true
|
||||||
|
ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET="$ONLYOFFICE_JWT_SECRET"
|
||||||
|
fi
|
||||||
|
|
||||||
set -a
|
set -a
|
||||||
. "$ENV_FILE"
|
. "$ENV_FILE"
|
||||||
set +a
|
set +a
|
||||||
@@ -61,6 +85,22 @@ if [ "$ENV_OVERRIDE_SERVER_HOST_SET" = true ]; then
|
|||||||
SERVER_HOST="$ENV_OVERRIDE_SERVER_HOST"
|
SERVER_HOST="$ENV_OVERRIDE_SERVER_HOST"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$ENV_OVERRIDE_ONLYOFFICE_ENABLED_SET" = true ]; then
|
||||||
|
ONLYOFFICE_ENABLED="$ENV_OVERRIDE_ONLYOFFICE_ENABLED"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL_SET" = true ]; then
|
||||||
|
ONLYOFFICE_PUBLIC_URL="$ENV_OVERRIDE_ONLYOFFICE_PUBLIC_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL_SET" = true ]; then
|
||||||
|
ONLYOFFICE_BACKEND_URL="$ENV_OVERRIDE_ONLYOFFICE_BACKEND_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET_SET" = true ]; then
|
||||||
|
ONLYOFFICE_JWT_SECRET="$ENV_OVERRIDE_ONLYOFFICE_JWT_SECRET"
|
||||||
|
fi
|
||||||
|
|
||||||
SERVER_STARTUP_TIMEOUT="${SERVER_STARTUP_TIMEOUT:-300}"
|
SERVER_STARTUP_TIMEOUT="${SERVER_STARTUP_TIMEOUT:-300}"
|
||||||
SETUP_COMPLETED="${SETUP_COMPLETED:-false}"
|
SETUP_COMPLETED="${SETUP_COMPLETED:-false}"
|
||||||
APP_DEBUG="${APP_DEBUG:-true}"
|
APP_DEBUG="${APP_DEBUG:-true}"
|
||||||
|
|||||||
@@ -190,10 +190,10 @@
|
|||||||
<div class="preview-viewer">
|
<div class="preview-viewer">
|
||||||
<div v-if="previewLoading" class="preview-status">正在加载预览...</div>
|
<div v-if="previewLoading" class="preview-status">正在加载预览...</div>
|
||||||
<div v-else-if="previewError" class="preview-status error">{{ previewError }}</div>
|
<div v-else-if="previewError" class="preview-status error">{{ previewError }}</div>
|
||||||
<div v-else-if="selectedDocument.previewKind === 'pdf' && previewBlobUrl" class="preview-embed-wrap">
|
<div v-else-if="previewMode === 'pdf' && previewBlobUrl" class="preview-embed-wrap">
|
||||||
<iframe :src="previewBlobUrl" class="preview-embed" title="PDF 预览"></iframe>
|
<iframe :src="previewBlobUrl" class="preview-embed" title="PDF 预览"></iframe>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="selectedDocument.previewKind === 'image' && previewBlobUrl" class="preview-image-wrap">
|
<div v-else-if="previewMode === 'image' && previewBlobUrl" class="preview-image-wrap">
|
||||||
<img :src="previewBlobUrl" :alt="selectedDocument.name" class="preview-image" />
|
<img :src="previewBlobUrl" :alt="selectedDocument.name" class="preview-image" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="shouldUseOnlyOffice" class="onlyoffice-preview-wrap">
|
<div v-else-if="shouldUseOnlyOffice" class="onlyoffice-preview-wrap">
|
||||||
@@ -201,7 +201,7 @@
|
|||||||
<div v-else-if="onlyOfficeError" class="preview-status error">{{ onlyOfficeError }}</div>
|
<div v-else-if="onlyOfficeError" class="preview-status error">{{ onlyOfficeError }}</div>
|
||||||
<div v-else :id="onlyOfficeHostId" class="onlyoffice-preview-host"></div>
|
<div v-else :id="onlyOfficeHostId" class="onlyoffice-preview-host"></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="selectedDocument.previewKind === 'table'" class="excel-preview-wrap">
|
<div v-else-if="previewMode === 'table'" class="excel-preview-wrap">
|
||||||
<div v-if="selectedDocument.previewPages.length > 1" class="excel-sheet-tabs" role="tablist" aria-label="Excel 工作表页签">
|
<div v-if="selectedDocument.previewPages.length > 1" class="excel-sheet-tabs" role="tablist" aria-label="Excel 工作表页签">
|
||||||
<button
|
<button
|
||||||
v-for="(page, index) in selectedDocument.previewPages"
|
v-for="(page, index) in selectedDocument.previewPages"
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
buildPreviewMetaLine,
|
buildPreviewMetaLine,
|
||||||
buildPreviewSecondaryMetaLine
|
buildPreviewSecondaryMetaLine
|
||||||
} from './policiesPreviewFormatters.js'
|
} from './policiesPreviewFormatters.js'
|
||||||
|
import { canUseOnlyOfficePreview, resolveKnowledgePreviewMode } from './knowledgePreviewMode.js'
|
||||||
|
|
||||||
function triggerFileDownload(blob, filename) {
|
function triggerFileDownload(blob, filename) {
|
||||||
const url = URL.createObjectURL(blob)
|
const url = URL.createObjectURL(blob)
|
||||||
@@ -27,12 +28,6 @@ const anchor = document.createElement('a')
|
|||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ONLYOFFICE_EXTENSIONS = new Set(['docx', 'xlsx', 'pptx'])
|
|
||||||
|
|
||||||
function supportsOnlyOfficePreview(document) {
|
|
||||||
return ONLYOFFICE_EXTENSIONS.has(String(document?.extension || '').toLowerCase())
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PoliciesView',
|
name: 'PoliciesView',
|
||||||
emits: ['summary-change'],
|
emits: ['summary-change'],
|
||||||
@@ -58,6 +53,7 @@ export default {
|
|||||||
const previewError = ref('')
|
const previewError = ref('')
|
||||||
const onlyOfficeLoading = ref(false)
|
const onlyOfficeLoading = ref(false)
|
||||||
const onlyOfficeError = ref('')
|
const onlyOfficeError = ref('')
|
||||||
|
const onlyOfficeAvailable = ref(false)
|
||||||
const onlyOfficeEditor = ref(null)
|
const onlyOfficeEditor = ref(null)
|
||||||
const onlyOfficeHostId = ref('knowledge-onlyoffice-preview')
|
const onlyOfficeHostId = ref('knowledge-onlyoffice-preview')
|
||||||
const currentPreviewPageIndex = ref(0)
|
const currentPreviewPageIndex = ref(0)
|
||||||
@@ -95,7 +91,12 @@ export default {
|
|||||||
const previewSecondaryMetaLine = computed(() =>
|
const previewSecondaryMetaLine = computed(() =>
|
||||||
buildPreviewSecondaryMetaLine(selectedDocument.value, activePreviewPage.value)
|
buildPreviewSecondaryMetaLine(selectedDocument.value, activePreviewPage.value)
|
||||||
)
|
)
|
||||||
const shouldUseOnlyOffice = computed(() => supportsOnlyOfficePreview(selectedDocument.value))
|
const previewMode = computed(() =>
|
||||||
|
resolveKnowledgePreviewMode(selectedDocument.value, {
|
||||||
|
onlyOfficeAvailable: onlyOfficeAvailable.value
|
||||||
|
})
|
||||||
|
)
|
||||||
|
const shouldUseOnlyOffice = computed(() => previewMode.value === 'onlyoffice')
|
||||||
const excelPreviewTable = computed(() =>
|
const excelPreviewTable = computed(() =>
|
||||||
selectedDocument.value?.previewKind === 'table'
|
selectedDocument.value?.previewKind === 'table'
|
||||||
? buildExcelPreviewTable(activePreviewPage.value)
|
? buildExcelPreviewTable(activePreviewPage.value)
|
||||||
@@ -119,6 +120,7 @@ export default {
|
|||||||
async function mountOnlyOfficeEditor(documentId) {
|
async function mountOnlyOfficeEditor(documentId) {
|
||||||
onlyOfficeLoading.value = true
|
onlyOfficeLoading.value = true
|
||||||
onlyOfficeError.value = ''
|
onlyOfficeError.value = ''
|
||||||
|
onlyOfficeAvailable.value = false
|
||||||
destroyOnlyOfficeEditor()
|
destroyOnlyOfficeEditor()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -133,8 +135,11 @@ export default {
|
|||||||
onlyOfficeHostId.value = `knowledge-onlyoffice-preview-${documentId}`
|
onlyOfficeHostId.value = `knowledge-onlyoffice-preview-${documentId}`
|
||||||
await nextTick()
|
await nextTick()
|
||||||
onlyOfficeEditor.value = new window.DocsAPI.DocEditor(onlyOfficeHostId.value, payload.config)
|
onlyOfficeEditor.value = new window.DocsAPI.DocEditor(onlyOfficeHostId.value, payload.config)
|
||||||
|
onlyOfficeAvailable.value = true
|
||||||
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
onlyOfficeError.value = error.message || 'ONLYOFFICE 预览加载失败。'
|
onlyOfficeError.value = error.message || 'ONLYOFFICE 预览加载失败。'
|
||||||
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
onlyOfficeLoading.value = false
|
onlyOfficeLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -172,6 +177,7 @@ export default {
|
|||||||
previewLoading.value = true
|
previewLoading.value = true
|
||||||
previewError.value = ''
|
previewError.value = ''
|
||||||
onlyOfficeError.value = ''
|
onlyOfficeError.value = ''
|
||||||
|
onlyOfficeAvailable.value = false
|
||||||
revokePreviewBlob()
|
revokePreviewBlob()
|
||||||
destroyOnlyOfficeEditor()
|
destroyOnlyOfficeEditor()
|
||||||
|
|
||||||
@@ -180,9 +186,11 @@ export default {
|
|||||||
selectedDocument.value = payload
|
selectedDocument.value = payload
|
||||||
currentPreviewPageIndex.value = 0
|
currentPreviewPageIndex.value = 0
|
||||||
|
|
||||||
if (supportsOnlyOfficePreview(payload)) {
|
if (canUseOnlyOfficePreview(payload)) {
|
||||||
await mountOnlyOfficeEditor(documentId)
|
await mountOnlyOfficeEditor(documentId)
|
||||||
} else if (payload.previewKind === 'pdf' || payload.previewKind === 'image') {
|
}
|
||||||
|
|
||||||
|
if (payload.previewKind === 'pdf' || payload.previewKind === 'image') {
|
||||||
const blob = await fetchKnowledgeDocumentBlob(documentId, 'inline')
|
const blob = await fetchKnowledgeDocumentBlob(documentId, 'inline')
|
||||||
previewBlobUrl.value = URL.createObjectURL(blob)
|
previewBlobUrl.value = URL.createObjectURL(blob)
|
||||||
}
|
}
|
||||||
@@ -290,6 +298,7 @@ export default {
|
|||||||
revokePreviewBlob()
|
revokePreviewBlob()
|
||||||
destroyOnlyOfficeEditor()
|
destroyOnlyOfficeEditor()
|
||||||
onlyOfficeError.value = ''
|
onlyOfficeError.value = ''
|
||||||
|
onlyOfficeAvailable.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPreviewPage(index) {
|
function selectPreviewPage(index) {
|
||||||
@@ -315,6 +324,7 @@ export default {
|
|||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
revokePreviewBlob()
|
revokePreviewBlob()
|
||||||
|
destroyOnlyOfficeEditor()
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -340,6 +350,7 @@ export default {
|
|||||||
onlyOfficeError,
|
onlyOfficeError,
|
||||||
onlyOfficeHostId,
|
onlyOfficeHostId,
|
||||||
onlyOfficeLoading,
|
onlyOfficeLoading,
|
||||||
|
previewMode,
|
||||||
previewMetaLine,
|
previewMetaLine,
|
||||||
previewSecondaryMetaLine,
|
previewSecondaryMetaLine,
|
||||||
previewBlobUrl,
|
previewBlobUrl,
|
||||||
|
|||||||
21
web/src/views/scripts/knowledgePreviewMode.js
Normal file
21
web/src/views/scripts/knowledgePreviewMode.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
const ONLYOFFICE_EXTENSIONS = new Set(['docx', 'xlsx', 'pptx'])
|
||||||
|
|
||||||
|
function supportsOnlyOfficePreview(document) {
|
||||||
|
return ONLYOFFICE_EXTENSIONS.has(String(document?.extension || '').toLowerCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveKnowledgePreviewMode(document, options = {}) {
|
||||||
|
if (!document) {
|
||||||
|
return 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportsOnlyOfficePreview(document) && options.onlyOfficeAvailable) {
|
||||||
|
return 'onlyoffice'
|
||||||
|
}
|
||||||
|
|
||||||
|
return document.previewKind || 'unsupported'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function canUseOnlyOfficePreview(document) {
|
||||||
|
return supportsOnlyOfficePreview(document)
|
||||||
|
}
|
||||||
39
web/tests/knowledge-preview-mode.test.mjs
Normal file
39
web/tests/knowledge-preview-mode.test.mjs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import assert from 'node:assert/strict'
|
||||||
|
|
||||||
|
import { resolveKnowledgePreviewMode } from '../src/views/scripts/knowledgePreviewMode.js'
|
||||||
|
|
||||||
|
function testPrefersOnlyOfficeForSupportedOfficeFileWhenAvailable() {
|
||||||
|
const document = {
|
||||||
|
extension: 'xlsx',
|
||||||
|
previewKind: 'table'
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(resolveKnowledgePreviewMode(document, { onlyOfficeAvailable: true }), 'onlyoffice')
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFallsBackToStructuredPreviewForOfficeFileWhenOnlyOfficeUnavailable() {
|
||||||
|
const document = {
|
||||||
|
extension: 'xlsx',
|
||||||
|
previewKind: 'table'
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(resolveKnowledgePreviewMode(document, { onlyOfficeAvailable: false }), 'table')
|
||||||
|
}
|
||||||
|
|
||||||
|
function testUsesPreviewKindForNonOnlyOfficeFile() {
|
||||||
|
const document = {
|
||||||
|
extension: 'pdf',
|
||||||
|
previewKind: 'pdf'
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(resolveKnowledgePreviewMode(document, { onlyOfficeAvailable: false }), 'pdf')
|
||||||
|
}
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
testPrefersOnlyOfficeForSupportedOfficeFileWhenAvailable()
|
||||||
|
testFallsBackToStructuredPreviewForOfficeFileWhenOnlyOfficeUnavailable()
|
||||||
|
testUsesPreviewKindForNonOnlyOfficeFile()
|
||||||
|
console.log('knowledge preview mode tests passed')
|
||||||
|
}
|
||||||
|
|
||||||
|
run()
|
||||||
Reference in New Issue
Block a user