Files
tyc-uniapp_V2/src/report-ui/vehicles/CQCXGYTS2.vue

251 lines
6.5 KiB
Vue
Raw Normal View History

2026-05-21 14:51:06 +08:00
<template>
<div class="card">
<div class="header-box">
<h3 class="header-title">人车核验详版</h3>
<p class="header-desc">展示人员与车辆的详细匹配结果及相关说明</p>
</div>
<div class="result-section" :class="resultSectionClass">
<div class="result-icon-wrap">
<span class="result-icon" :class="iconClass">
{{ iconChar }}
</span>
</div>
<div class="result-label">认证结果</div>
<div class="result-value" :class="resultTextClass">{{ resultText }}</div>
<p v-if="resultDesc" class="result-desc">{{ resultDesc }}</p>
</div>
<div v-if="hasParams" class="info-rows">
<div class="info-row">
<span class="info-label">姓名</span>
<span class="info-value">{{ maskedName }}</span>
</div>
<div class="info-row">
<span class="info-label">车牌号</span>
<span class="info-value font-mono">{{ params?.plate_no || params?.car_license || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">号牌类型</span>
<span class="info-value">{{ params?.carplate_type || params?.car_type || '-' }}</span>
</div>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue';
import { useRiskNotifier } from '@/composables/useRiskNotifier';
const props = defineProps({
data: { type: Object, default: () => ({}) },
params: { type: Object, default: () => ({}) },
apiId: { type: String, default: '' },
index: { type: Number, default: 0 },
notifyRiskStatus: { type: Function, default: () => { } },
});
const maskedName = computed(() => {
const name = props.params?.name || '';
if (!name) return '-';
return name.length > 1 ? name[0] + '*'.repeat(name.length - 1) : '*';
});
// status: 0 一致, -1 不一致, -2 非法姓名, -4 无记录
const status = computed(() => {
const s = props.data?.status;
if (s === 0 || s === -1 || s === -2 || s === -4) return s;
return null;
});
const resultText = computed(() => {
const s = status.value;
if (s === 0) return '一致';
if (s === -1) return '不一致';
if (s === -2) return '非法姓名';
if (s === -4) return '无记录';
return '暂无结果';
});
const resultDesc = computed(() => {
const s = status.value;
if (s === -2) return '姓名长度或格式不正确,请核对后重试';
if (s === -4) return '未查询到相关核验记录';
return '';
});
const resultTextClass = computed(() => {
const s = status.value;
if (s === 0) return 'result-match';
if (s === -1) return 'result-mismatch';
if (s === -2) return 'result-invalid';
if (s === -4) return 'result-norecord';
return 'result-unknown';
});
const resultSectionClass = computed(() => {
const s = status.value;
if (s === 0) return 'result-section match';
if (s === -1) return 'result-section mismatch';
if (s === -2) return 'result-section invalid';
if (s === -4) return 'result-section norecord';
return 'result-section unknown';
});
const iconClass = computed(() => {
const s = status.value;
if (s === 0) return 'icon-match';
if (s === -1) return 'icon-mismatch';
if (s === -2) return 'icon-invalid';
if (s === -4) return 'icon-norecord';
return 'icon-unknown';
});
const iconChar = computed(() => {
const s = status.value;
if (s === 0) return '✓';
if (s === -1) return '✕';
if (s === -2) return '!';
if (s === -4) return '—';
return '?';
});
const hasParams = computed(() => {
const p = props.params || {};
return p.name || p.plate_no || p.car_license || p.carplate_type || p.car_type;
});
const riskScore = computed(() => 100);
useRiskNotifier(props, riskScore);
defineExpose({ riskScore });
</script>
<style scoped>
.card {
@apply bg-white rounded-lg p-4 shadow-sm border border-gray-100;
}
.header-box {
@apply rounded-lg mb-4 p-4;
background: linear-gradient(135deg, #5c6bc0 0%, #3949ab 100%);
color: #fff;
}
.header-title {
@apply text-lg font-semibold m-0;
}
.header-desc {
@apply text-sm mt-1 opacity-90 m-0;
}
.result-section {
@apply rounded-xl p-5 text-center mb-4;
}
.result-section.match {
background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%);
border: 1px solid rgba(76, 175, 80, 0.3);
}
.result-section.mismatch {
background: linear-gradient(135deg, #ffebee 0%, #ffcdd2 100%);
border: 1px solid rgba(244, 67, 54, 0.3);
}
.result-section.invalid {
background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
border: 1px solid rgba(255, 152, 0, 0.4);
}
.result-section.norecord {
background: linear-gradient(135deg, #eceff1 0%, #cfd8dc 100%);
border: 1px solid rgba(96, 125, 139, 0.3);
}
.result-section.unknown {
@apply bg-gray-50 border border-gray-200;
}
.result-icon-wrap {
@apply mb-2;
}
.result-icon {
@apply inline-flex items-center justify-center w-12 h-12 rounded-full text-2xl font-bold text-white;
}
.result-icon.icon-match {
background: linear-gradient(135deg, #43a047 0%, #2e7d32 100%);
box-shadow: 0 2px 8px rgba(76, 175, 80, 0.4);
}
.result-icon.icon-mismatch {
background: linear-gradient(135deg, #e53935 0%, #c62828 100%);
box-shadow: 0 2px 8px rgba(244, 67, 54, 0.4);
}
.result-icon.icon-invalid {
background: linear-gradient(135deg, #fb8c00 0%, #ef6c00 100%);
box-shadow: 0 2px 8px rgba(255, 152, 0, 0.4);
}
.result-icon.icon-norecord {
background: linear-gradient(135deg, #78909c 0%, #546e7a 100%);
box-shadow: 0 2px 8px rgba(96, 125, 139, 0.3);
}
.result-icon.icon-unknown {
background: linear-gradient(135deg, #78909c 0%, #546e7a 100%);
box-shadow: 0 2px 8px rgba(96, 125, 139, 0.3);
}
.result-label {
@apply text-sm text-gray-500 mb-1;
}
.result-value {
@apply text-xl font-semibold;
}
.result-desc {
@apply text-sm mt-2 m-0 text-gray-600 max-w-xs mx-auto;
}
.result-match {
color: #2e7d32;
}
.result-mismatch {
color: #c62828;
}
.result-invalid {
color: #e65100;
}
.result-norecord {
color: #546e7a;
}
.result-unknown {
@apply text-gray-500;
}
.info-rows {
@apply space-y-3 pt-2 border-t border-gray-100;
}
.info-row {
@apply flex items-center text-sm;
}
.info-label {
@apply w-20 text-gray-500 shrink-0;
}
.info-value {
@apply font-medium text-gray-800;
}
</style>