适配来源消息只读任务展示

This commit is contained in:
andy committed 2026-07-10 19:38:13 +08:00
1 parent bbd4ea22df
commit 1efa819599
11 files changed
+324 -14

No files matched your search

@@ -25,6 +25,7 @@
</span>
<div class="task-links">
<RouterLink
v-if="!isSourceMessageOnlyDetail"
class="task-link"
:to="`/reservation/orders/${detail.order_id}`"
>
@@ -74,6 +75,50 @@
</dl>
</section>
<section
v-if="isSourceMessageOnlyDetail"
class="source-only-result"
>
<header>
<h2>{{ t('task.sourceOnlyResult') }}</h2>
<p>{{ t('task.sourceOnlyReadonly') }}</p>
</header>
<dl v-if="sourceMessageOnlyResult">
<div>
<dt>{{ t('task.entryResultCode') }}</dt>
<dd class="th-code">
{{ sourceMessageOnlyResult.entry_result_code || '-' }}
</dd>
</div>
<div>
<dt>{{ t('task.entryResultMeaning') }}</dt>
<dd>{{ sourceMessageOnlyResult.entry_result_meaning || '-' }}</dd>
</div>
<div>
<dt>{{ t('task.entryResultDescription') }}</dt>
<dd>{{ sourceMessageOnlyResult.entry_result_description || '-' }}</dd>
</div>
<div>
<dt>{{ t('task.entryResultSourceMessageId') }}</dt>
<dd class="th-code">
{{ sourceMessageOnlyResult.entry_result_source_message_id || '-' }}
</dd>
</div>
<div class="source-only-result__raw">
<dt>{{ t('task.rawAnswer') }}</dt>
<dd>
<pre>{{ sourceMessageOnlyResult.raw_answer || '-' }}</pre>
</dd>
</div>
</dl>
<p
v-else
class="source-only-result__empty"
>
{{ t('task.noSourceOnlyResult') }}
</p>
</section>
<div
v-if="detail.availability.blocked"
class="task-alert"
@@ -105,7 +150,7 @@
<div class="task-detail-body">
<div class="task-card-main">
<ReservationManualReviewConversionPanel
v-if="isManualReviewTask"
v-if="isManualReviewTask && !isSourceMessageOnlyDetail"
:busy="mutationBusy !== null"
@submit="submitManualReviewConversion"
/>
@@ -152,6 +197,7 @@
<aside class="task-side-stack">
<ReservationOperaPanel
v-if="!isSourceMessageOnlyDetail"
:task-id="detail.task_id"
:operations="detail.opera_operations"
:executable="detail.availability.executable && canExecuteOpera"
@@ -198,7 +244,11 @@ import {
validateReservationFieldValues,
type ReservationFieldValidationErrors,
} from '@/utils/reservationFieldRules'
import { formatReservationMaybeStableReason, formatReservationTaskCard } from '@/utils/reservationDisplay'
import {
formatReservationMaybeStableReason,
formatReservationTaskCard,
isReservationSourceMessageOnlyTask,
} from '@/utils/reservationDisplay'
import { formatReservationDateTime } from '@/utils/reservationFormat'
import { useAuthStore } from '@/stores/authStore'
@@ -219,9 +269,17 @@ const validationErrors = ref<ReservationFieldValidationErrors>({})
const validationSummaryActive = ref(false)
const mutationBusy = ref<'save' | 'confirm' | 'manual-convert' | null>(null)
const canEditTask = computed(() => authStore.hasPermission('RESERVATION_TASK_EDIT'))
const canConfirmTask = computed(() => authStore.hasPermission('RESERVATION_TASK_CONFIRM'))
const canExecuteOpera = computed(() => authStore.hasPermission('RESERVATION_OPERA_SIM_EXECUTE'))
const isSourceMessageOnlyDetail = computed(() =>
isReservationSourceMessageOnlyTask(detail.value?.system_task_type, detail.value?.task_card_type),
)
const sourceMessageOnlyResult = computed(() => detail.value?.source_message_only_result ?? null)
const canEditTask = computed(() => authStore.hasPermission('RESERVATION_TASK_EDIT') && !isSourceMessageOnlyDetail.value)
const canConfirmTask = computed(
() => authStore.hasPermission('RESERVATION_TASK_CONFIRM') && !isSourceMessageOnlyDetail.value,
)
const canExecuteOpera = computed(
() => authStore.hasPermission('RESERVATION_OPERA_SIM_EXECUTE') && !isSourceMessageOnlyDetail.value,
)
const canViewAudit = computed(() => authStore.hasPermission('RESERVATION_AUDIT_READ'))
const canSave = computed(() => canEditTask.value && Boolean(detail.value?.availability.editable))
const canConfirm = computed(() => canConfirmTask.value && Boolean(detail.value?.availability.confirmable))
@@ -503,35 +561,81 @@ function replaceOperation(operation: ReservationOperaOperationResult): void {
padding: 16px;
}
.source-only-result {
display: grid;
gap: 12px;
border: 1px solid var(--th-color-blue-100);
border-radius: var(--th-radius-md);
background: var(--th-color-blue-100);
padding: 16px;
}
.task-evidence h2,
.task-evidence dl {
.task-evidence dl,
.source-only-result h2,
.source-only-result p,
.source-only-result dl {
margin: 0;
}
.task-evidence h2 {
.task-evidence h2,
.source-only-result h2 {
color: var(--th-color-slate-900);
font-size: 15px;
}
.source-only-result header {
display: grid;
gap: 6px;
}
.source-only-result header p,
.source-only-result__empty {
color: var(--th-color-slate-500);
font-size: 13px;
line-height: 1.6;
}
.task-evidence dl {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px;
}
.source-only-result dl {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.task-evidence dt {
color: var(--th-color-slate-500);
font-size: 12px;
font-weight: 700;
}
.task-evidence dd {
.task-evidence dd,
.source-only-result dd {
margin: 5px 0 0;
color: var(--th-color-slate-900);
font-size: 13px;
overflow-wrap: anywhere;
}
.source-only-result__raw {
grid-column: 1 / -1;
}
.source-only-result pre {
max-height: 180px;
overflow: auto;
border: 1px solid var(--th-color-slate-200);
border-radius: var(--th-radius-sm);
background: var(--th-color-white);
padding: 10px;
white-space: pre-wrap;
}
.task-alert,
.task-notice {
display: flex;
@@ -617,7 +721,8 @@ function replaceOperation(operation: ReservationOperaOperationResult): void {
}
@media (max-width: 640px) {
.task-evidence dl {
.task-evidence dl,
.source-only-result dl {
grid-template-columns: 1fr;
}
}