feat(web): 工作台 AI 模式报销预审与文档查询模型拆分

- 新增 aiApplicationPrecheckModel/aiDocumentQueryModel/aiApplicationPreviewActions/aiConversationHtmlRenderer 四个独立模型与服务,按职责从主组件拆出
- PersonalWorkbenchAiMode 接入拆分后的预审、文档查询与 HTML 渲染逻辑,配合 markdown 工具增强结构化展示
- 文档中心与归档筛选、风险可见性、申请预览等工具同步适配,补充对应单元测试
- 新增 AI 文档卡片背景资源
This commit is contained in:
caoxiaozhu
2026-06-20 10:17:37 +08:00
parent 3d69f8501f
commit 304bbe1fd4
26 changed files with 3974 additions and 117 deletions

View File

@@ -928,6 +928,11 @@
letter-spacing: 0;
}
.workbench-ai-answer-markdown :deep(.ai-html-flow) {
display: grid;
gap: 16px;
}
.workbench-ai-answer-markdown :deep(h1),
.workbench-ai-answer-markdown :deep(h2),
.workbench-ai-answer-markdown :deep(h3),
@@ -987,7 +992,331 @@
color: #475569;
}
.workbench-ai-answer-markdown :deep(.markdown-table-wrap) {
.workbench-ai-answer-markdown :deep(.ai-html-callout) {
margin: 0;
padding: 14px 16px;
border-left: 3px solid rgba(37, 99, 235, 0.5);
border-radius: 12px;
background: rgba(239, 246, 255, 0.62);
color: #475569;
}
.workbench-ai-answer-markdown :deep(.ai-html-focus-grid) {
display: grid;
gap: 0;
margin: 2px 0 18px;
padding-left: 22px;
border-left: 3px solid rgba(96, 165, 250, 0.66);
}
.workbench-ai-answer-markdown :deep(.ai-html-focus-card) {
padding: 11px 0 16px;
border: 0;
border-radius: 0;
background: transparent;
}
.workbench-ai-answer-markdown :deep(.ai-html-focus-card + .ai-html-focus-card) {
border-top: 1px solid rgba(226, 232, 240, 0.92);
}
.workbench-ai-answer-markdown :deep(.ai-html-focus-label) {
display: block;
margin-bottom: 4px;
color: #1d4ed8;
font-size: 15px;
font-weight: 900;
}
.workbench-ai-answer-markdown :deep(.ai-html-focus-card p) {
color: #475569;
font-size: 16px;
font-weight: 650;
line-height: 1.72;
}
.workbench-ai-answer-markdown :deep(.ai-html-steps),
.workbench-ai-answer-markdown :deep(.ai-html-list) {
display: grid;
gap: 12px;
margin: 0;
padding: 0;
list-style: none;
}
.workbench-ai-answer-markdown :deep(.ai-html-steps li) {
display: grid;
grid-template-columns: 34px minmax(0, 1fr);
gap: 16px;
align-items: start;
}
.workbench-ai-answer-markdown :deep(.ai-html-step-index) {
width: 34px;
min-height: 28px;
display: grid;
align-items: start;
justify-items: start;
padding-top: 1px;
border-radius: 0;
background: transparent;
color: #1d4ed8;
font-size: 17px;
font-weight: 900;
line-height: 1.45;
}
.workbench-ai-answer-markdown :deep(.ai-html-step-copy) {
display: grid;
gap: 5px;
}
.workbench-ai-answer-markdown :deep(.ai-html-step-copy > strong) {
color: #0f172a;
font-size: 17px;
line-height: 1.45;
}
.workbench-ai-answer-markdown :deep(.ai-html-step-copy > p) {
color: #475569;
font-size: 16px;
font-weight: 620;
line-height: 1.72;
}
.workbench-ai-answer-markdown :deep(.ai-html-list:not(.ai-html-steps)) {
padding-left: 18px;
list-style: disc;
}
.workbench-ai-answer-markdown :deep(.ai-html-list--ordered) {
padding-left: 22px;
list-style: decimal;
}
.workbench-ai-answer-markdown :deep(.ai-document-card-list) {
display: grid;
gap: 12px;
margin-top: 18px;
}
.workbench-ai-answer-markdown :deep(.ai-document-card) {
position: relative;
display: grid;
gap: 12px;
padding: 16px 18px;
border: 1px solid rgba(226, 232, 240, 0.9);
border-left: 3px solid #cbd5e1;
border-radius: 12px;
background: #ffffff;
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 4px 12px rgba(15, 23, 42, 0.04);
color: #334155;
animation: workbenchDocumentCardReveal 360ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}
.workbench-ai-answer-markdown :deep(.ai-document-card:hover) {
border-color: rgba(148, 163, 184, 0.7);
box-shadow: 0 2px 4px rgba(15, 23, 42, 0.05), 0 8px 20px rgba(15, 23, 42, 0.07);
transform: translateY(-1px);
}
.workbench-ai-answer-markdown :deep(.ai-document-card:nth-child(2)) {
animation-delay: 40ms;
}
.workbench-ai-answer-markdown :deep(.ai-document-card:nth-child(3)) {
animation-delay: 80ms;
}
.workbench-ai-answer-markdown :deep(.ai-document-card:nth-child(4)) {
animation-delay: 120ms;
}
/* 状态语义色:左侧边条颜色随状态变化,一眼判断当前阶段 */
.workbench-ai-answer-markdown :deep(.ai-document-card.is-pending) {
border-left-color: #2563eb;
}
.workbench-ai-answer-markdown :deep(.ai-document-card.is-success) {
border-left-color: #16a34a;
}
.workbench-ai-answer-markdown :deep(.ai-document-card.is-warning) {
border-left-color: #d97706;
}
.workbench-ai-answer-markdown :deep(.ai-document-card.is-danger) {
border-left-color: #dc2626;
}
/* 卡片头部:状态 + 类型(左) · 单据编号(右) */
.workbench-ai-answer-markdown :deep(.ai-document-card__head) {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-width: 0;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__head-left) {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
flex-wrap: wrap;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__status) {
display: inline-flex;
align-items: center;
min-height: 22px;
padding: 0 9px;
border-radius: 6px;
background: rgba(148, 163, 184, 0.16);
color: #475569;
font-size: 12px;
font-weight: 700;
line-height: 1.2;
white-space: nowrap;
}
.workbench-ai-answer-markdown :deep(.ai-document-card.is-pending .ai-document-card__status) {
background: rgba(37, 99, 235, 0.1);
color: #1d4ed8;
}
.workbench-ai-answer-markdown :deep(.ai-document-card.is-success .ai-document-card__status) {
background: rgba(22, 163, 74, 0.1);
color: #15803d;
}
.workbench-ai-answer-markdown :deep(.ai-document-card.is-warning .ai-document-card__status) {
background: rgba(217, 119, 6, 0.1);
color: #b45309;
}
.workbench-ai-answer-markdown :deep(.ai-document-card.is-danger .ai-document-card__status) {
background: rgba(220, 38, 38, 0.1);
color: #b91c1c;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__type) {
color: #64748b;
font-size: 12px;
font-weight: 500;
line-height: 1.3;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__number) {
flex: 0 0 auto;
color: #94a3b8;
font-size: 12px;
font-weight: 500;
line-height: 1.3;
overflow-wrap: anywhere;
}
/* 卡片主体:事由(主焦点) + 申请人/部门(次焦点) */
.workbench-ai-answer-markdown :deep(.ai-document-card__body) {
display: grid;
gap: 6px;
min-width: 0;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__reason) {
display: -webkit-box;
color: #0f172a;
font-size: 16px;
font-weight: 700;
line-height: 1.45;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__owner-line) {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 6px;
min-width: 0;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__owner) {
color: #1e293b;
font-size: 13px;
font-weight: 600;
line-height: 1.3;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__dept) {
color: #64748b;
font-size: 13px;
font-weight: 500;
line-height: 1.3;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__dot) {
color: #cbd5e1;
font-size: 12px;
font-weight: 700;
}
/* 卡片底部:辅助元信息(左) · 金额(右) · 操作 */
.workbench-ai-answer-markdown :deep(.ai-document-card__foot) {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding-top: 12px;
border-top: 1px solid rgba(226, 232, 240, 0.9);
}
.workbench-ai-answer-markdown :deep(.ai-document-card__meta) {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 6px;
min-width: 0;
flex: 1 1 auto;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__meta-item) {
color: #64748b;
font-size: 12px;
font-weight: 500;
line-height: 1.3;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__amount-block) {
display: grid;
justify-items: end;
gap: 1px;
flex: 0 0 auto;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__amount-label) {
color: #94a3b8;
font-size: 11px;
font-weight: 500;
line-height: 1.2;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__amount) {
color: #0f172a;
font-size: 17px;
font-weight: 700;
line-height: 1.2;
white-space: nowrap;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__action) {
flex: 0 0 auto;
}
.workbench-ai-answer-markdown :deep(.markdown-table-wrap),
.workbench-ai-answer-markdown :deep(.ai-html-table-wrap) {
overflow-x: auto;
margin-top: 18px;
border: 1px solid rgba(226, 232, 240, 0.9);
@@ -1013,6 +1342,384 @@
font-weight: 850;
}
.workbench-ai-answer-markdown :deep(.ai-html-image-frame) {
margin: 0;
overflow: hidden;
border: 1px solid rgba(226, 232, 240, 0.9);
border-radius: 16px;
background: rgba(248, 250, 252, 0.74);
}
.workbench-ai-answer-markdown :deep(.ai-html-image),
.workbench-ai-answer-markdown :deep(.ai-html-inline-image) {
max-width: 100%;
height: auto;
display: block;
}
.workbench-ai-answer-markdown :deep(.ai-html-image) {
width: 100%;
object-fit: contain;
}
.workbench-ai-answer-markdown :deep(.ai-html-inline-image) {
max-height: 220px;
margin: 8px 0;
border-radius: 12px;
}
.workbench-ai-answer-markdown :deep(.ai-html-image-caption) {
display: block;
padding: 8px 12px;
color: #64748b;
font-size: 12px;
font-weight: 700;
}
.workbench-ai-answer-markdown :deep(.markdown-action-link),
.workbench-ai-answer-markdown :deep(.ai-html-action-link) {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 28px;
padding: 0 10px;
border-radius: 999px;
background: rgba(37, 99, 235, 0.1);
color: #1d4ed8;
font-size: 13px;
font-weight: 850;
line-height: 1.2;
text-decoration: none;
white-space: nowrap;
}
.workbench-ai-answer-markdown :deep(.markdown-action-link:hover),
.workbench-ai-answer-markdown :deep(.ai-html-action-link:hover) {
background: rgba(37, 99, 235, 0.16);
color: #1e40af;
}
@keyframes workbenchDocumentCardReveal {
from {
opacity: 0;
transform: translateY(10px) scale(0.985);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@media (prefers-reduced-motion: reduce) {
.workbench-ai-answer-markdown :deep(.ai-document-card) {
animation: none;
transition: none;
}
}
@media (max-width: 720px) {
.workbench-ai-answer-markdown :deep(.ai-document-card) {
padding: 14px;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__head) {
align-items: flex-start;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__number) {
flex-basis: 100%;
text-align: left;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__foot) {
flex-wrap: wrap;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__amount-block) {
justify-items: start;
order: 2;
}
.workbench-ai-answer-markdown :deep(.ai-document-card__action) {
order: 3;
margin-left: auto;
}
}
.workbench-ai-application-preview {
min-width: 0;
display: grid;
gap: 16px;
margin-top: 18px;
}
.structured-card-reveal-enter-active,
.structured-card-reveal-leave-active {
transition:
opacity 260ms cubic-bezier(0.2, 0.8, 0.2, 1),
transform 260ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.structured-card-reveal-enter-from,
.structured-card-reveal-leave-to {
opacity: 0;
transform: translateY(10px) scale(0.99);
}
.structured-card-reveal-enter-to,
.structured-card-reveal-leave-from {
opacity: 1;
transform: translateY(0) scale(1);
}
.application-preview-table {
display: grid;
overflow: hidden;
border: 1px solid rgba(191, 219, 254, 0.72);
border-radius: 14px;
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(248, 250, 252, 0.96)),
#ffffff;
box-shadow:
0 16px 34px rgba(15, 23, 42, 0.07),
inset 0 1px 0 rgba(255, 255, 255, 0.98);
color: #334155;
font-size: 15px;
}
.application-preview-row {
position: relative;
display: grid;
grid-template-columns: 148px minmax(0, 1fr);
min-height: 48px;
border-top: 1px solid rgba(226, 232, 240, 0.96);
}
.structured-card-reveal-enter-active .application-preview-row {
animation: workbenchApplicationRowReveal 260ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.structured-card-reveal-enter-active .application-preview-row:nth-child(2) {
animation-delay: 35ms;
}
.structured-card-reveal-enter-active .application-preview-row:nth-child(3) {
animation-delay: 70ms;
}
.structured-card-reveal-enter-active .application-preview-row:nth-child(4) {
animation-delay: 105ms;
}
.structured-card-reveal-enter-active .application-preview-row:nth-child(5) {
animation-delay: 140ms;
}
.structured-card-reveal-enter-active .application-preview-row:nth-child(n + 6) {
animation-delay: 165ms;
}
.application-preview-row:first-child {
border-top: 0;
}
.application-preview-row.head {
min-height: 42px;
background: linear-gradient(180deg, rgba(239, 246, 255, 0.92), rgba(248, 250, 252, 0.98));
color: #334155;
font-size: 13px;
font-weight: 900;
}
.application-preview-row > span {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
padding: 10px 16px;
}
.application-preview-label {
border-right: 1px solid rgba(226, 232, 240, 0.96);
background: rgba(248, 250, 252, 0.72);
color: #475569;
font-weight: 820;
}
.application-preview-value {
position: relative;
color: #0f172a;
font-weight: 700;
}
.application-preview-row.editable {
cursor: pointer;
}
.application-preview-row.editable:hover,
.application-preview-row.editable:hover .application-preview-label,
.application-preview-row.editable:hover .application-preview-value {
background: rgba(239, 246, 255, 0.58);
}
.application-preview-row.editable:focus-visible {
z-index: 1;
outline: 2px solid rgba(37, 99, 235, 0.42);
outline-offset: -2px;
}
.application-preview-row.highlight .application-preview-label {
background: rgba(219, 234, 254, 0.76);
color: #1d4ed8;
}
.application-preview-row.highlight .application-preview-value {
background: rgba(219, 234, 254, 0.44);
color: #1e40af;
font-weight: 850;
}
.application-preview-row.missing {
background: rgba(37, 99, 235, 0.035);
box-shadow: inset 3px 0 0 rgba(37, 99, 235, 0.5);
}
.application-preview-row.missing .application-preview-label {
background: rgba(219, 234, 254, 0.78);
color: #1d4ed8;
font-weight: 900;
}
.application-preview-row.missing .application-preview-value {
background: rgba(239, 246, 255, 0.74);
font-weight: 850;
}
.application-preview-text {
min-width: 0;
overflow-wrap: anywhere;
line-height: 1.48;
}
.application-preview-input {
width: 100%;
min-width: 0;
min-height: 34px;
padding: 0 10px;
border: 1px solid rgba(37, 99, 235, 0.46);
border-radius: 8px;
outline: none;
background: #ffffff;
color: #0f172a;
font: inherit;
font-weight: 720;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.11);
}
.application-preview-select {
cursor: pointer;
}
.application-preview-edit-btn {
flex: 0 0 auto;
width: 28px;
height: 28px;
display: inline-grid;
place-items: center;
border: 1px solid rgba(37, 99, 235, 0.18);
border-radius: 8px;
background: rgba(239, 246, 255, 0.92);
color: #1d4ed8;
cursor: pointer;
opacity: 0;
transition:
opacity 160ms ease,
border-color 160ms ease,
background 160ms ease,
transform 160ms ease;
}
.application-preview-edit-btn i {
font-size: 15px;
}
.application-preview-row:hover .application-preview-edit-btn,
.application-preview-edit-btn:focus-visible {
opacity: 1;
}
.application-preview-edit-btn:hover,
.application-preview-edit-btn:focus-visible {
border-color: rgba(37, 99, 235, 0.38);
background: rgba(219, 234, 254, 0.98);
transform: translateY(-1px);
}
.application-preview-footer {
color: #334155;
font-size: 15px;
font-weight: 720;
line-height: 1.78;
}
.application-preview-footer.workbench-ai-answer-markdown {
margin-top: 0;
}
.application-preview-footer-missing {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px 6px;
padding: 2px 0 0;
color: #334155;
font-size: 15px;
font-weight: 760;
line-height: 1.75;
}
.application-preview-missing-prefix,
.application-preview-missing-suffix {
color: #334155;
font-weight: 850;
}
.application-preview-missing-list {
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 4px;
}
.application-preview-missing-chip {
display: inline-flex;
align-items: center;
min-height: 24px;
padding: 0 8px;
border-radius: 8px;
background: rgba(37, 99, 235, 0.1);
color: #1d4ed8;
font-size: 13px;
font-weight: 900;
}
.application-preview-missing-separator {
color: #1d4ed8;
font-weight: 820;
}
@keyframes workbenchApplicationRowReveal {
from {
opacity: 0;
transform: translateY(6px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.workbench-ai-suggested-actions {
display: flex;
flex-wrap: wrap;
@@ -1445,10 +2152,16 @@
.workbench-ai-panel-swap-leave-active,
.workbench-ai-thinking-collapse-enter-active,
.workbench-ai-thinking-collapse-leave-active,
.structured-card-reveal-enter-active,
.structured-card-reveal-leave-active,
.workbench-ai-confirm-fade-enter-active,
.workbench-ai-confirm-fade-leave-active,
.workbench-ai-confirm-fade-enter-active .workbench-ai-confirm-dialog,
.workbench-ai-confirm-fade-leave-active .workbench-ai-confirm-dialog {
transition: none;
}
.structured-card-reveal-enter-active .application-preview-row {
animation: none;
}
}