Files
report_viewer/src/ui/CIVYZA1B3.vue
2026-05-13 11:01:42 +08:00

240 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="card">
<div class="header-box">
<h3 class="header-title">公安三要素</h3>
<p class="header-desc">比对人像与身份证信息是否为同一人</p>
</div>
<div v-if="hasData" class="result-section" :class="scoreLevelClass">
<div class="result-main">
<div class="result-label">系统判断</div>
<div class="result-value" :class="scoreTextClass">
{{ msg || scoreConclusion }}
</div>
</div>
<div class="result-score">
相似度分值<span class="font-semibold">{{ scoreDisplay }}</span>
<span class="text-xs text-gray-500 ml-1">(01越高越相似)</span>
</div>
</div>
<div v-if="hasBaseInfo" class="info-block">
<div class="block-title">被核验人信息</div>
<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">{{ sex || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">生日</span>
<span class="info-value">{{ birthdayDisplay }}</span>
</div>
<div class="info-row">
<span class="info-label">户籍地址</span>
<span class="info-value">{{ address || '-' }}</span>
</div>
</div>
<div v-if="!hasData" class="empty-tip">暂无核验结果</div>
</div>
</template>
<script setup>
import { computed } from 'vue';
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 hasData = computed(() => props.data && Object.keys(props.data).length > 0);
const score = computed(() => {
const v = props.data?.score;
if (typeof v === 'number') return v;
const n = Number(v);
return Number.isFinite(n) ? n : null;
});
const msg = computed(() => props.data?.msg || '');
const incorrect = computed(() => props.data?.incorrect ?? null);
const sex = computed(() => props.data?.sex || '');
const birthday = computed(() => props.data?.birthday || '');
const address = computed(() => props.data?.address || '');
const scoreDisplay = computed(() => {
if (score.value == null) return '-';
return score.value.toFixed(2);
});
const scoreConclusion = computed(() => {
const s = score.value;
if (s == null) return '暂无结论';
if (s < 0.4) return '系统判断为不同人';
if (s < 0.45) return '不能确定是否为同一人';
return '系统判断为同一人';
});
const scoreLevelClass = computed(() => {
const s = score.value;
if (s == null) return 'result-section unknown';
if (s < 0.4) return 'result-section bad';
if (s < 0.45) return 'result-section warn';
return 'result-section ok';
});
const scoreTextClass = computed(() => {
const s = score.value;
if (s == null) return 'result-unknown';
if (s < 0.4) return 'result-bad';
if (s < 0.45) return 'result-warn';
return 'result-ok';
});
const birthdayDisplay = computed(() => {
const b = birthday.value;
if (!b || b.length !== 8) return b || '-';
const y = b.slice(0, 4);
const m = b.slice(4, 6);
const d = b.slice(6, 8);
return `${y}-${m}-${d}`;
});
const maskedName = computed(() => {
const name = props.params?.name || '';
if (!name) return '-';
return name.length > 1 ? name[0] + '*'.repeat(name.length - 1) : '*';
});
const hasBaseInfo = computed(() => sex.value || birthday.value || address.value || props.params?.name);
</script>
<style scoped>
.card {
padding: 1rem;
}
.header-box {
margin-bottom: 1rem;
}
.header-title {
font-size: 1.125rem;
font-weight: 600;
}
.header-desc {
font-size: 0.875rem;
color: #6b7280;
margin-top: 0.25rem;
}
.result-section {
padding: 0.75rem 0.875rem;
border-radius: 0.75rem;
margin-bottom: 1rem;
border: 1px solid #e5e7eb;
}
.result-section.ok {
background: #ecfdf3;
border-color: #22c55e33;
}
.result-section.bad {
background: #fef2f2;
border-color: #ef444433;
}
.result-section.warn {
background: #fffbeb;
border-color: #f9731633;
}
.result-section.unknown {
background: #f9fafb;
}
.result-main {
display: flex;
align-items: center;
justify-content: space-between;
}
.result-label {
font-size: 0.875rem;
color: #6b7280;
}
.result-value {
font-size: 1rem;
font-weight: 600;
}
.result-ok {
color: #16a34a;
}
.result-bad {
color: #dc2626;
}
.result-warn {
color: #d97706;
}
.result-unknown {
color: #6b7280;
}
.result-score {
margin-top: 0.5rem;
font-size: 0.875rem;
color: #4b5563;
}
.info-block {
margin-top: 1rem;
padding: 0.75rem 0.875rem;
border-radius: 0.75rem;
background: #f9fafb;
}
.block-title {
font-size: 0.875rem;
font-weight: 600;
color: #374151;
margin-bottom: 0.5rem;
}
.info-row {
display: flex;
justify-content: space-between;
font-size: 0.875rem;
padding: 0.15rem 0;
}
.info-label {
color: #6b7280;
}
.info-value {
color: #111827;
margin-left: 1rem;
text-align: right;
}
.empty-tip {
color: #9ca3af;
font-size: 0.875rem;
padding: 1rem 0;
text-align: center;
}
</style>