feat: 新增归档中心页面并完善知识库与报销查询能力

新增前端归档中心视图及相关工具函数,扩充知识库文档分类和
提取器支持多种格式,增强编排器报销查询的多维度检索,优
化本体规则和用户代理审核消息,前端完善报销创建和审批详
情交互细节,补充单元测试覆盖。
This commit is contained in:
caoxiaozhu
2026-05-22 16:00:19 +08:00
parent 1f15699013
commit 88ff04bef8
120 changed files with 6236 additions and 643 deletions

View File

@@ -8,6 +8,76 @@ const markdown = new MarkdownIt({
const defaultTableOpen = markdown.renderer.rules.table_open
const defaultTableClose = markdown.renderer.rules.table_close
const defaultParagraphOpen = markdown.renderer.rules.paragraph_open
const defaultLinkOpen = markdown.renderer.rules.link_open
const defaultBlockquoteOpen = markdown.renderer.rules.blockquote_open
const ACTION_LINK_CLASS_BY_HREF = {
'#confirm-attachment-association': 'markdown-action-link-confirm'
}
function resolveActionLinkClass(href) {
const normalizedHref = String(href || '').trim()
return ACTION_LINK_CLASS_BY_HREF[normalizedHref] || ''
}
function inlineTokenHasActionLink(token) {
const children = Array.isArray(token?.children) ? token.children : []
return children.some((child) => (
child?.type === 'link_open' && resolveActionLinkClass(child.attrGet?.('href'))
))
}
function resolveInlineTokenPlainText(token) {
const children = Array.isArray(token?.children) ? token.children : []
const childText = children
.filter((child) => ['text', 'code_inline'].includes(String(child?.type || '')))
.map((child) => String(child?.content || ''))
.join('')
.trim()
return childText || String(token?.content || '').replace(/[*_`]+/g, '').trim()
}
function blockquoteHasAttachmentHeading(tokens, idx) {
for (let i = idx + 1; i < tokens.length; i += 1) {
const token = tokens[i]
if (token?.type === 'blockquote_close') {
return false
}
if (token?.type === 'inline') {
return /^附件\s*\d+\s*[:]/.test(resolveInlineTokenPlainText(token))
}
}
return false
}
markdown.renderer.rules.paragraph_open = (tokens, idx, options, env, self) => {
if (inlineTokenHasActionLink(tokens[idx + 1])) {
tokens[idx].attrJoin('class', 'markdown-action-paragraph')
}
return defaultParagraphOpen
? defaultParagraphOpen(tokens, idx, options, env, self)
: self.renderToken(tokens, idx, options)
}
markdown.renderer.rules.link_open = (tokens, idx, options, env, self) => {
const actionClass = resolveActionLinkClass(tokens[idx].attrGet('href'))
if (actionClass) {
tokens[idx].attrJoin('class', `markdown-action-link ${actionClass}`)
}
return defaultLinkOpen
? defaultLinkOpen(tokens, idx, options, env, self)
: self.renderToken(tokens, idx, options)
}
markdown.renderer.rules.blockquote_open = (tokens, idx, options, env, self) => {
if (blockquoteHasAttachmentHeading(tokens, idx)) {
tokens[idx].attrJoin('class', 'markdown-attachment-card')
}
return defaultBlockquoteOpen
? defaultBlockquoteOpen(tokens, idx, options, env, self)
: self.renderToken(tokens, idx, options)
}
markdown.renderer.rules.table_open = (tokens, idx, options, env, self) => (
`<div class="markdown-table-wrap">${defaultTableOpen ? defaultTableOpen(tokens, idx, options, env, self) : '<table>'}`