feat(web): AI 工作台会话与文档卡片渲染增强
- aiConversationHtmlRenderer 识别单据记录类表格并渲染为卡片列表,新增删除申请单详情的禁用占位链接 - aiWorkbenchConversationStore 增加草稿删除后会话链接失效处理,避免点击已删除单据跳转 - aiApplicationPreviewActions 调整提交/草稿调用路径,PersonalWorkbenchAiMode 接入新的会话存储与渲染 - ConfirmDialog/TravelRequestDeleteDialog/useAppShell/AppShellRouteView 配套适配,同步更新相关前端测试
This commit is contained in:
@@ -1140,8 +1140,11 @@ function canShowInlineSuggestedActions(message = {}) {
|
||||
function isInlineSuggestedActionDisabled(action = {}, message = {}) {
|
||||
const actionType = String(action?.action_type || '').trim()
|
||||
return (
|
||||
[AI_APPLICATION_ACTION_SAVE_DRAFT, AI_APPLICATION_ACTION_SUBMIT].includes(actionType) &&
|
||||
isApplicationPreviewEstimatePending(message)
|
||||
Boolean(action?.disabled) ||
|
||||
(
|
||||
[AI_APPLICATION_ACTION_SAVE_DRAFT, AI_APPLICATION_ACTION_SUBMIT].includes(actionType) &&
|
||||
isApplicationPreviewEstimatePending(message)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1267,8 +1270,21 @@ function normalizeInlineApplicationResultTableCell(value, fallback = '-') {
|
||||
}
|
||||
|
||||
function buildInlineApplicationActionDetailHref(reference = '') {
|
||||
const value = String(reference || '').trim()
|
||||
return value ? `${AI_APPLICATION_DETAIL_HREF_PREFIX}${encodeURIComponent(value)}` : ''
|
||||
const source = reference && typeof reference === 'object' ? reference : { reference }
|
||||
const claimId = String(source.claimId || source.claim_id || source.id || '').trim()
|
||||
const claimNo = String(source.claimNo || source.claim_no || source.documentNo || source.document_no || '').trim()
|
||||
const fallback = String(source.reference || '').trim()
|
||||
if (claimId || claimNo) {
|
||||
const params = new URLSearchParams()
|
||||
if (claimId) {
|
||||
params.set('claim_id', claimId)
|
||||
}
|
||||
if (claimNo) {
|
||||
params.set('claim_no', claimNo)
|
||||
}
|
||||
return `${AI_APPLICATION_DETAIL_HREF_PREFIX}${encodeURIComponent(params.toString())}`
|
||||
}
|
||||
return fallback ? `${AI_APPLICATION_DETAIL_HREF_PREFIX}${encodeURIComponent(fallback)}` : ''
|
||||
}
|
||||
|
||||
function resolveInlineApplicationActionDocumentInfo(draftPayload = {}) {
|
||||
@@ -1293,7 +1309,7 @@ function resolveInlineApplicationActionDocumentInfo(draftPayload = {}) {
|
||||
function buildInlineApplicationResultTable(draftPayload = {}, options = {}) {
|
||||
const info = resolveInlineApplicationActionDocumentInfo(draftPayload)
|
||||
const reference = info.claimNo || info.claimId
|
||||
const href = buildInlineApplicationActionDetailHref(reference)
|
||||
const href = buildInlineApplicationActionDetailHref(info)
|
||||
const actionText = href ? `[查看](${href})` : '-'
|
||||
return [
|
||||
'| 单据类型 | 单据编号 | 单据状态 | 当前节点 | 操作 |',
|
||||
@@ -1945,22 +1961,40 @@ function parseAiApplicationDetailHref(href = '') {
|
||||
if (!encodedReference) {
|
||||
return null
|
||||
}
|
||||
let reference = ''
|
||||
try {
|
||||
const reference = decodeURIComponent(encodedReference).trim()
|
||||
return reference ? { reference } : null
|
||||
reference = decodeURIComponent(encodedReference).trim()
|
||||
} catch {
|
||||
return { reference: encodedReference }
|
||||
reference = encodedReference.trim()
|
||||
}
|
||||
if (!reference) {
|
||||
return null
|
||||
}
|
||||
const params = new URLSearchParams(reference)
|
||||
const claimId = String(params.get('claim_id') || '').trim()
|
||||
const claimNo = String(params.get('claim_no') || '').trim()
|
||||
if (claimId || claimNo) {
|
||||
return {
|
||||
reference: claimNo || claimId,
|
||||
claimId,
|
||||
claimNo
|
||||
}
|
||||
}
|
||||
return { reference }
|
||||
}
|
||||
|
||||
function buildAiDocumentDetailRequest(detailReference = {}) {
|
||||
const reference = String(detailReference.reference || '').trim()
|
||||
const isApplication = /^APP?-/i.test(reference)
|
||||
const claimId = String(detailReference.claimId || detailReference.claim_id || '').trim()
|
||||
const claimNo = String(detailReference.claimNo || detailReference.claim_no || '').trim()
|
||||
const lookupReference = claimId || reference
|
||||
const displayReference = claimNo || reference
|
||||
const isApplication = /^APP?-/i.test(displayReference) || Boolean(claimId || claimNo)
|
||||
return {
|
||||
id: reference,
|
||||
claimId: reference,
|
||||
claimNo: reference,
|
||||
documentNo: reference,
|
||||
id: lookupReference,
|
||||
claimId: claimId || reference,
|
||||
claimNo: claimNo || reference,
|
||||
documentNo: displayReference,
|
||||
documentType: isApplication ? 'application' : 'reimbursement',
|
||||
documentTypeCode: isApplication ? 'application' : 'reimbursement',
|
||||
detailLookupOnly: true,
|
||||
@@ -2371,7 +2405,11 @@ function handleInlineSuggestedAction(action = {}, sourceMessage = null) {
|
||||
if (actionType === 'open_application_detail') {
|
||||
const claimNo = String(actionPayload.claim_no || actionPayload.claimNo || '').trim()
|
||||
const claimId = String(actionPayload.claim_id || actionPayload.claimId || '').trim()
|
||||
emit('open-document', buildAiDocumentDetailRequest({ reference: claimNo || claimId }))
|
||||
emit('open-document', buildAiDocumentDetailRequest({
|
||||
reference: claimNo || claimId,
|
||||
claimId,
|
||||
claimNo
|
||||
}))
|
||||
return
|
||||
}
|
||||
if (actionPayload.steward_confirm_flow && actionPayload.flow_id === 'travel_reimbursement') {
|
||||
|
||||
@@ -321,6 +321,55 @@ function handleCancel() {
|
||||
max-height: min(420px, calc(100dvh - 292px));
|
||||
}
|
||||
|
||||
.shared-confirm-card--destructive {
|
||||
width: min(420px, calc(100vw - 40px));
|
||||
gap: 12px;
|
||||
padding: 20px 22px;
|
||||
border-color: rgba(var(--danger-rgb), 0.16);
|
||||
border-radius: 6px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255, 255, 255, 0.99), rgba(248, 250, 252, 0.97));
|
||||
box-shadow:
|
||||
0 18px 42px rgba(15, 23, 42, 0.16),
|
||||
0 1px 0 rgba(255, 255, 255, 0.92) inset;
|
||||
}
|
||||
|
||||
.shared-confirm-card--destructive .shared-confirm-badge {
|
||||
min-height: 24px;
|
||||
padding: 0 9px;
|
||||
font-size: 11px;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.shared-confirm-card--destructive h4 {
|
||||
font-size: 19px;
|
||||
line-height: 1.42;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.shared-confirm-card--destructive p {
|
||||
max-width: 34em;
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
.shared-confirm-card--destructive .shared-confirm-actions {
|
||||
gap: 8px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.shared-confirm-card--destructive .shared-confirm-btn {
|
||||
min-width: 112px;
|
||||
min-height: 38px;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.shared-confirm-card--destructive .shared-confirm-btn.confirm.danger {
|
||||
box-shadow: 0 10px 20px rgba(var(--danger-rgb), 0.18);
|
||||
}
|
||||
|
||||
.shared-confirm-card--compact h4 {
|
||||
font-size: 15px;
|
||||
line-height: 1.35;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
badge-tone="danger"
|
||||
:title="title"
|
||||
:description="description"
|
||||
size="destructive"
|
||||
actions-align="end"
|
||||
cancel-text="取消"
|
||||
confirm-text="确认删除"
|
||||
busy-text="删除中..."
|
||||
|
||||
Reference in New Issue
Block a user