feat(web): 更新应用外壳路由视图和政策制度页面,增强前端路由嵌套和页面展示能力
This commit is contained in:
@@ -31,6 +31,8 @@ import { resolveKnowledgePreviewLayoutState } from './knowledgePreviewLayout.js'
|
||||
import { resolveInitialKnowledgeFolder } from './knowledgeFolderSelection.js'
|
||||
import { buildOnlyOfficePreviewConfig } from './onlyOfficePreviewConfig.js'
|
||||
|
||||
const KNOWLEDGE_POLL_INTERVAL_MS = 5000
|
||||
|
||||
function triggerFileDownload(blob, filename) {
|
||||
const url = URL.createObjectURL(blob)
|
||||
const anchor = document.createElement('a')
|
||||
@@ -42,6 +44,7 @@ function triggerFileDownload(blob, filename) {
|
||||
|
||||
let bodyOverflowSnapshot = ''
|
||||
let bodyOverscrollBehaviorSnapshot = ''
|
||||
let libraryPollTimer = 0
|
||||
|
||||
function setBodyScrollLocked(isLocked) {
|
||||
if (typeof document === 'undefined') {
|
||||
@@ -270,20 +273,26 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadLibrary(options = {}) {
|
||||
loading.value = true
|
||||
try {
|
||||
const payload = await fetchKnowledgeLibrary()
|
||||
folders.value = payload.folders || []
|
||||
documents.value = payload.documents || []
|
||||
emit('summary-change', { totalDocuments: documents.value.length })
|
||||
|
||||
async function loadLibrary(options = {}) {
|
||||
loading.value = true
|
||||
try {
|
||||
const payload = await fetchKnowledgeLibrary()
|
||||
folders.value = payload.folders || []
|
||||
documents.value = payload.documents || []
|
||||
emit('summary-change', { totalDocuments: documents.value.length })
|
||||
|
||||
activeFolder.value = resolveInitialKnowledgeFolder(folders.value, activeFolder.value)
|
||||
|
||||
|
||||
if (options.preserveSelection && selectedDocument.value?.id) {
|
||||
const exists = documents.value.some((doc) => doc.id === selectedDocument.value.id)
|
||||
const nextDocument = documents.value.find((doc) => doc.id === selectedDocument.value.id)
|
||||
const exists = Boolean(nextDocument)
|
||||
if (!exists) {
|
||||
closePreview()
|
||||
} else {
|
||||
selectedDocument.value = {
|
||||
...selectedDocument.value,
|
||||
...nextDocument
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.preserveSelection && llmWikiDocument.value?.document_id) {
|
||||
@@ -292,11 +301,12 @@ export default {
|
||||
closeLlmWikiSummary()
|
||||
}
|
||||
}
|
||||
syncLibraryPolling()
|
||||
} catch (error) {
|
||||
emit('summary-change', { totalDocuments: 0 })
|
||||
toast(error.message || '知识库加载失败。')
|
||||
} finally {
|
||||
loading.value = false
|
||||
emit('summary-change', { totalDocuments: 0 })
|
||||
toast(error.message || '知识库加载失败。')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,10 +361,37 @@ export default {
|
||||
...patch
|
||||
}
|
||||
}
|
||||
syncLibraryPolling()
|
||||
}
|
||||
|
||||
function hasSyncingDocuments() {
|
||||
return documents.value.some((doc) => Number(doc?.stateCode || 0) === 2)
|
||||
}
|
||||
|
||||
function stopLibraryPolling() {
|
||||
if (libraryPollTimer) {
|
||||
window.clearInterval(libraryPollTimer)
|
||||
libraryPollTimer = 0
|
||||
}
|
||||
}
|
||||
|
||||
function startLibraryPolling() {
|
||||
stopLibraryPolling()
|
||||
libraryPollTimer = window.setInterval(() => {
|
||||
loadLibrary({ preserveSelection: true })
|
||||
}, KNOWLEDGE_POLL_INTERVAL_MS)
|
||||
}
|
||||
|
||||
function syncLibraryPolling() {
|
||||
if (hasSyncingDocuments()) {
|
||||
startLibraryPolling()
|
||||
return
|
||||
}
|
||||
stopLibraryPolling()
|
||||
}
|
||||
|
||||
function resolveIngestActionLabel(document) {
|
||||
if (ingestingId.value === document.id) {
|
||||
if (ingestingId.value === document.id || Number(document?.stateCode || 0) === 2) {
|
||||
return '归纳中'
|
||||
}
|
||||
return Number(document?.stateCode || 0) === 3 ? '重新归纳' : '归纳'
|
||||
@@ -372,27 +409,64 @@ export default {
|
||||
}
|
||||
|
||||
function canViewLlmWiki(document) {
|
||||
return isAdmin.value && Number(document?.stateCode || 0) === 3
|
||||
return isAdmin.value && Boolean(document?.llmWikiAvailable)
|
||||
}
|
||||
|
||||
function resolveViewLlmWikiTitle(document) {
|
||||
if (!isAdmin.value) {
|
||||
return '仅管理员可查看 LLM Wiki 归纳内容'
|
||||
}
|
||||
if (document?.llmWikiAvailable && Number(document?.stateCode || 0) === 4) {
|
||||
return '查看本次降级归纳结果,仅供人工排查,不能视为正式知识'
|
||||
}
|
||||
if (document?.llmWikiAvailable && document?.llmWikiQualityStatus === 'partial_degraded') {
|
||||
return '查看当前归纳结果,存在部分降级分组,请人工复核'
|
||||
}
|
||||
if (document?.llmWikiAvailable) {
|
||||
return '查看并编辑当前文档的 LLM Wiki 归纳内容'
|
||||
}
|
||||
if (Number(document?.stateCode || 0) === 2) {
|
||||
return 'Hermes 正在归纳当前文档,完成后可查看 LLM Wiki 知识总结'
|
||||
}
|
||||
if (Number(document?.stateCode || 0) === 4) {
|
||||
return '当前文档上次归纳失败,请重新归纳后再查看'
|
||||
return '当前文档上次归纳失败,且没有可查看的 LLM Wiki 产物'
|
||||
}
|
||||
if (Number(document?.stateCode || 0) !== 3) {
|
||||
return '文档尚未完成归纳,暂无可查看的 LLM Wiki 知识总结'
|
||||
}
|
||||
return '查看并编辑当前文档的 LLM Wiki 归纳内容'
|
||||
return '查看当前文档的 LLM Wiki 归纳内容'
|
||||
}
|
||||
|
||||
function resolveLlmWikiQualityLabel(document) {
|
||||
const qualityStatus = String(document?.quality_status || '').trim()
|
||||
if (qualityStatus === 'partial_degraded') {
|
||||
return '部分降级'
|
||||
}
|
||||
if (qualityStatus === 'fallback_only') {
|
||||
return '降级兜底'
|
||||
}
|
||||
if (qualityStatus === 'runtime_only') {
|
||||
return '非 Hermes 结果'
|
||||
}
|
||||
if (qualityStatus === 'failed') {
|
||||
return '归纳失败'
|
||||
}
|
||||
return '正式归纳'
|
||||
}
|
||||
|
||||
function resolveLlmWikiQualityTone(document) {
|
||||
const qualityStatus = String(document?.quality_status || '').trim()
|
||||
if (qualityStatus === 'formal') {
|
||||
return 'success'
|
||||
}
|
||||
if (qualityStatus === 'partial_degraded') {
|
||||
return 'warning'
|
||||
}
|
||||
return 'danger'
|
||||
}
|
||||
|
||||
async function handleManualIngest(document) {
|
||||
if (!isAdmin.value || ingestingId.value || !document?.id) {
|
||||
if (!isAdmin.value || ingestingId.value || !document?.id || Number(document?.stateCode || 0) === 2) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -406,19 +480,13 @@ export default {
|
||||
try {
|
||||
const payload = await syncKnowledgeDocumentToLlmWiki({
|
||||
folder: document.folder,
|
||||
documentId: document.id
|
||||
documentId: document.id,
|
||||
force: true
|
||||
})
|
||||
await loadLibrary({ preserveSelection: true })
|
||||
if (selectedDocument.value?.id === document.id) {
|
||||
await selectDocument(document.id)
|
||||
}
|
||||
toast(payload.summary || 'Hermes 已完成文档归纳。')
|
||||
toast(payload.summary || 'Hermes 已进入后台归纳。')
|
||||
} catch (error) {
|
||||
patchDocumentState(document.id, {
|
||||
stateCode: 4,
|
||||
state: '归纳失败',
|
||||
stateTone: 'danger'
|
||||
})
|
||||
await loadLibrary({ preserveSelection: true })
|
||||
toast(error.message || 'Hermes 归纳文档失败。')
|
||||
} finally {
|
||||
ingestingId.value = ''
|
||||
@@ -654,6 +722,7 @@ export default {
|
||||
revokePreviewBlob()
|
||||
destroyOnlyOfficeEditor()
|
||||
setBodyScrollLocked(false)
|
||||
stopLibraryPolling()
|
||||
window.removeEventListener('keydown', handleWindowKeydown)
|
||||
})
|
||||
|
||||
@@ -711,6 +780,8 @@ export default {
|
||||
selectedDocument,
|
||||
resolveIngestActionLabel,
|
||||
resolveIngestActionTitle,
|
||||
resolveLlmWikiQualityLabel,
|
||||
resolveLlmWikiQualityTone,
|
||||
resolveViewLlmWikiTitle,
|
||||
saveLlmWikiSummary,
|
||||
totalCount,
|
||||
|
||||
Reference in New Issue
Block a user