diff --git a/web/src/assets/styles/components/personal-workbench-ai-mode.css b/web/src/assets/styles/components/personal-workbench-ai-mode.css index 50cfd73..3142704 100644 --- a/web/src/assets/styles/components/personal-workbench-ai-mode.css +++ b/web/src/assets/styles/components/personal-workbench-ai-mode.css @@ -1094,30 +1094,84 @@ list-style: decimal; } +.workbench-ai-answer-markdown :deep(.ai-document-query-summary) { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 8px 12px; + margin-top: 0; + padding: 2px 0 0; + border: 0; + background: transparent; + color: #334155; +} + +.workbench-ai-answer-markdown :deep(.ai-document-query-summary__label) { + display: inline-flex; + align-items: center; + min-height: auto; + padding: 0; + border-radius: 0; + background: transparent; + color: #64748b; + font-size: 13px; + font-weight: 760; + line-height: 1.2; +} + +.workbench-ai-answer-markdown :deep(.ai-document-query-summary__scope) { + min-width: 0; + color: #0f172a; + font-size: 15px; + font-weight: 860; + line-height: 1.5; + overflow-wrap: anywhere; +} + +.workbench-ai-answer-markdown :deep(.ai-document-query-summary__count) { + display: inline-flex; + align-items: baseline; + gap: 4px; + color: #64748b; + font-size: 14px; + font-weight: 700; + line-height: 1.4; +} + +.workbench-ai-answer-markdown :deep(.ai-document-query-summary__count strong) { + color: #1d4ed8; + font-size: 14px; + font-weight: 900; +} + .workbench-ai-answer-markdown :deep(.ai-document-card-list) { display: grid; - gap: 12px; - margin-top: 18px; + gap: 16px; + margin-top: 14px; } .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; + gap: 0; + overflow: hidden; + padding: 0; + border: 1px solid rgba(203, 213, 225, 0.76); + border-left: 0; 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); + background: rgba(255, 255, 255, 0.96); + box-shadow: + 0 1px 2px rgba(15, 23, 42, 0.035), + 0 10px 26px rgba(15, 23, 42, 0.045); 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); + border-color: rgba(148, 163, 184, 0.72); + background: #ffffff; + box-shadow: 0 8px 22px rgba(15, 23, 42, 0.065); transform: translateY(-1px); } @@ -1133,186 +1187,161 @@ 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; + gap: 16px; 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; + padding: 13px 18px; + background: rgba(37, 99, 235, 0.11); } .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; + min-height: 24px; + padding: 0; + border-radius: 0; + background: transparent; + color: #1d4ed8; + font-size: 15px; + font-weight: 860; + line-height: 1.3; white-space: nowrap; } +.workbench-ai-answer-markdown :deep(.ai-document-card.is-success .ai-document-card__head) { + background: rgba(22, 163, 74, 0.1); +} + +.workbench-ai-answer-markdown :deep(.ai-document-card.is-warning .ai-document-card__head) { + background: rgba(217, 119, 6, 0.12); +} + +.workbench-ai-answer-markdown :deep(.ai-document-card.is-danger .ai-document-card__head) { + background: rgba(220, 38, 38, 0.1); +} + .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; + gap: 14px; min-width: 0; + padding: 16px 18px 18px; } .workbench-ai-answer-markdown :deep(.ai-document-card__reason) { display: -webkit-box; - color: #0f172a; - font-size: 16px; - font-weight: 700; + min-width: 0; + color: #1e40af; + font-size: 15px; + font-weight: 760; line-height: 1.45; overflow: hidden; - -webkit-line-clamp: 2; + -webkit-line-clamp: 1; -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.is-success .ai-document-card__reason) { + color: #166534; } -.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.is-warning .ai-document-card__reason) { + color: #92400e; } -.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.is-danger .ai-document-card__reason) { + color: #991b1b; } -.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) { +.workbench-ai-answer-markdown :deep(.ai-document-card__details) { display: grid; - justify-items: end; - gap: 1px; - flex: 0 0 auto; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px 28px; + padding-top: 2px; + border-top: 1px solid rgba(203, 213, 225, 0.76); } -.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__field) { + display: grid; + grid-template-columns: 86px minmax(0, 1fr); + align-items: center; + gap: 14px; + min-width: 0; +} + +.workbench-ai-answer-markdown :deep(.ai-document-card__field--action) { + grid-column: 1 / -1; +} + +.workbench-ai-answer-markdown :deep(.ai-document-card__label) { + color: #8a94a6; + font-size: 13px; + font-weight: 640; + line-height: 1.4; + white-space: nowrap; +} + +.workbench-ai-answer-markdown :deep(.ai-document-card__value) { + min-width: 0; + color: #334155; + font-size: 14px; + font-weight: 720; + line-height: 1.45; + overflow-wrap: anywhere; } .workbench-ai-answer-markdown :deep(.ai-document-card__amount) { color: #0f172a; - font-size: 17px; - font-weight: 700; + font-size: 18px; + font-weight: 900; line-height: 1.2; white-space: nowrap; } +.workbench-ai-answer-markdown :deep(.ai-document-card__number) { + color: #64748b; + font-size: 13px; + font-weight: 740; + letter-spacing: 0; +} + .workbench-ai-answer-markdown :deep(.ai-document-card__action) { - flex: 0 0 auto; + display: inline-flex; + align-items: center; + width: fit-content; + min-height: 26px; + padding: 0; + border-radius: 0; + background: transparent; + color: #1d4ed8; + font-size: 14px; + font-weight: 820; + box-shadow: none; + white-space: nowrap; +} + +.workbench-ai-answer-markdown :deep(.ai-document-card__action:hover) { + background: transparent; + color: #1e40af; + text-decoration: underline; } .workbench-ai-answer-markdown :deep(.markdown-table-wrap), @@ -1547,31 +1576,37 @@ } .workbench-ai-answer-markdown :deep(.ai-document-card) { - padding: 14px; + padding: 0; } .workbench-ai-answer-markdown :deep(.ai-document-card__head) { align-items: flex-start; + flex-direction: column; + gap: 8px; + padding: 12px 14px; + } + + .workbench-ai-answer-markdown :deep(.ai-document-card__body) { + padding: 14px; + } + + .workbench-ai-answer-markdown :deep(.ai-document-card__details) { + grid-template-columns: 1fr; + gap: 10px; + } + + .workbench-ai-answer-markdown :deep(.ai-document-card__field) { + grid-template-columns: 76px minmax(0, 1fr); + gap: 10px; + } + + .workbench-ai-answer-markdown :deep(.ai-document-card__field--action) { + grid-column: auto; } .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 { diff --git a/web/src/composables/useAppShell.js b/web/src/composables/useAppShell.js index 87c2bcf..491c521 100644 --- a/web/src/composables/useAppShell.js +++ b/web/src/composables/useAppShell.js @@ -10,6 +10,7 @@ import { fetchOntologyParse } from '../services/ontology.js' import { fetchLatestConversation } from '../services/orchestrator.js' import { markAiWorkbenchConversationDraftDeleted } from '../utils/aiWorkbenchConversationStore.js' import { clearAssistantSessionSnapshotForDraftClaim } from '../utils/assistantSessionSnapshot.js' +import { isApplicationDocumentNo } from '../utils/documentClassification.js' import { ASSISTANT_SCOPE_SESSION_STEWARD, buildUnsupportedBusinessScopeConversation, @@ -428,8 +429,7 @@ export function useAppShell() { return ( documentType === 'application' || documentType === 'expense_application' - || normalizedClaimNo.startsWith('AP-') - || normalizedClaimNo.startsWith('APP-') + || isApplicationDocumentNo(normalizedClaimNo) ) } diff --git a/web/src/composables/useRequests.js b/web/src/composables/useRequests.js index 5cb033c..91cd956 100644 --- a/web/src/composables/useRequests.js +++ b/web/src/composables/useRequests.js @@ -1,6 +1,7 @@ import { computed, reactive, ref } from 'vue' import { fetchAllExpenseClaims } from '../services/reimbursements.js' +import { isApplicationDocumentNo } from '../utils/documentClassification.js' import { filterActionableRiskFlags, normalizeRiskFlagTone } from '../utils/riskFlags.js' const EXPENSE_TYPE_LABELS = { @@ -212,8 +213,7 @@ function resolveDocumentTypeMeta(claim, typeCode) { const isApplication = explicitType === DOCUMENT_TYPE_APPLICATION || explicitType === 'expense_application' - || claimNo.startsWith('AP-') - || claimNo.startsWith('APP-') + || isApplicationDocumentNo(claimNo) || normalizedType === 'application' || normalizedType.endsWith('_application') diff --git a/web/src/utils/aiDocumentQueryModel.js b/web/src/utils/aiDocumentQueryModel.js index 26e6c7e..9cb63d5 100644 --- a/web/src/utils/aiDocumentQueryModel.js +++ b/web/src/utils/aiDocumentQueryModel.js @@ -1,4 +1,5 @@ import { extractExpenseClaimItems } from '../services/reimbursements.js' +import { isApplicationDocumentNo } from './documentClassification.js' const DOCUMENT_QUERY_LIMIT = 8 @@ -336,8 +337,7 @@ function resolveDocumentTypeCode(claim = {}) { || explicitType === 'expense_application' || expenseType === 'application' || expenseType.endsWith('_application') - || documentNo.startsWith('AP-') - || documentNo.startsWith('APP-') + || isApplicationDocumentNo(documentNo) ) { return 'application' } @@ -679,49 +679,66 @@ function buildDocumentCardHtml(record = {}) { const typeClass = record.documentType === 'application' ? 'application' : 'reimbursement' const statusTone = record.statusTone || 'is-pending' const amountLabel = record.documentType === 'application' ? '预计金额' : '报销金额' - - // footer 左侧辅助元信息:业务地点(可选)+ 时间 - const metaParts = [] - if (record.locationLabel) { - metaParts.push(``) - } - metaParts.push(``) - const metaHtml = `
` + const ownerText = [record.ownerLabel, record.departmentLabel] + .filter((item) => item && item !== '未显示') + .join(' · ') || '未显示' return [ `