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

228 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="resultSectionClass">
<div class="result-main">
<div class="result-label">验证结果</div>
<div class="result-value" :class="resultClass">
{{ stateText }}
</div>
</div>
</div>
<div v-if="hasParams" 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 font-mono">{{ maskedIdCard }}</span>
</div>
<div class="info-row">
<span class="info-label">银行卡号</span>
<span class="info-value font-mono">{{ maskedBankCard }}</span>
</div>
<div class="info-row">
<span class="info-label">预留手机号</span>
<span class="info-value font-mono">{{ maskedMobile }}</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 state = computed(() => props.data?.state || '');
const stateText = computed(() => {
switch (state.value) {
case '1':
return '验证一致';
case '2':
return '认证不一致:此卡已过期或卡号无效';
case '3':
return '认证不一致:认证未通过';
case '4':
return '认证不一致:今日验证次数过多,请明日再试';
case '5':
return '认证不一致:当前提交数量过多,请降低提交频率';
case '6':
return '认证不一致:持卡人信息有误或卡状态异常';
case '7':
return '认证不一致:未开通无卡支付或发卡行不支持该卡验证';
case '8':
return '认证不一致:认证受限';
default:
return '暂无结果';
}
});
const resultClass = computed(() => {
if (state.value === '1') return 'result-ok';
if (!state.value) return 'result-unknown';
return 'result-bad';
});
const resultSectionClass = computed(() => {
if (state.value === '1') return 'result-section ok';
if (!state.value) return 'result-section unknown';
return 'result-section bad';
});
const maskedName = computed(() => {
const name = props.params?.name || '';
if (!name) return '-';
return name.length > 1 ? name[0] + '*'.repeat(name.length - 1) : '*';
});
const maskedIdCard = computed(() => {
const id = props.params?.id_card || '';
if (!id || id.length < 8) return id || '-';
return id.slice(0, 4) + '********' + id.slice(-4);
});
const maskedBankCard = computed(() => {
const card = props.params?.bank_card || '';
if (!card || card.length < 8) return card || '-';
return card.slice(0, 4) + '********' + card.slice(-4);
});
const maskedMobile = computed(() => {
const m = props.params?.mobile || props.params?.mobile_no || '';
if (!m || m.length < 7) return m || '-';
return m.slice(0, 3) + '****' + m.slice(-4);
});
const hasParams = computed(() => {
const p = props.params || {};
return p.name || p.id_card || p.bank_card || p.mobile || p.mobile_no;
});
</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.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-unknown {
color: #6b7280;
}
.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>