310 lines
13 KiB
Vue
310 lines
13 KiB
Vue
<template>
|
||
<div class="card shadow-sm rounded-xl overflow-hidden p-4">
|
||
<div class="border border-[#EEEEEE] rounded-xl">
|
||
<!-- 标题 -->
|
||
<div class="flex items-center mb-3 p-4">
|
||
<div class="w-8 h-8 flex items-center justify-center mr-2">
|
||
<img src="@/assets/images/report/ssfxztgl.png" alt="限高/失信风险" class="w-8 h-8 object-contain" />
|
||
</div>
|
||
<span class="font-bold text-gray-800">限高 / 失信风险</span>
|
||
</div>
|
||
|
||
<!-- 风险整体概览 -->
|
||
<div class="px-4 mb-4">
|
||
<div class="grid grid-cols-1 md:grid-cols-3 gap-3">
|
||
<div class="p-3 rounded-lg bg-[#EB3C3C1A] border border-[#EB3C3C4D]">
|
||
<div class="text-xs text-gray-600 mb-1">规则最终决策</div>
|
||
<div class="text-lg font-semibold" :class="finalDecision === 'Accept' ? 'text-green-600' : 'text-red-600'">
|
||
{{ finalDecisionText }}
|
||
</div>
|
||
<div v-if="finalWeight" class="text-xs text-gray-500 mt-1">
|
||
风险权重:{{ finalWeight }}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="p-3 rounded-lg bg-[#D6943E1A] border border-[#D6943E4D]">
|
||
<div class="text-xs text-gray-600 mb-1">失信记录</div>
|
||
<div class="text-lg font-semibold text-orange-600">
|
||
{{ sxList.length }} 条
|
||
</div>
|
||
<div class="text-xs text-gray-500 mt-1">
|
||
命中失信被执行人公告
|
||
</div>
|
||
</div>
|
||
|
||
<div class="p-3 rounded-lg bg-[#2B79EE1A] border border-[#2B79EE4D]">
|
||
<div class="text-xs text-gray-600 mb-1">限高记录</div>
|
||
<div class="text-lg font-semibold text-blue-600">
|
||
{{ xgList.length }} 条
|
||
</div>
|
||
<div class="text-xs text-gray-500 mt-1">
|
||
{{ recentLimitDesc }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 失信记录 -->
|
||
<div v-if="sxList.length" class="px-4 mb-4">
|
||
<LTitle title="失信被执行人记录" />
|
||
<div class="space-y-3">
|
||
<div v-for="(item, index) in sxList" :key="'sx_' + index" class="case-wrapper">
|
||
<div class="bg-white rounded-xl overflow-hidden border px-4 pt-3 border-[#DDDDDD]">
|
||
<div class="cursor-pointer relative" @click="toggleExpand('sx', index)">
|
||
<div class="flex items-center">
|
||
<div class="font-bold text-base text-[#333333] mr-2">
|
||
{{ item.casecode || '暂无案号' }}
|
||
</div>
|
||
<span class="px-2 py-1 text-xs rounded-md font-medium bg-[#F9ECEC] text-[#EB3C3C]">
|
||
{{ item.datatype || '失信被执行人' }}
|
||
</span>
|
||
</div>
|
||
<div class="pb-2 text-sm">
|
||
<span class="text-[#666666]">立案:</span>
|
||
<span class="text-[#333333]">{{ item.regdate || '-' }}</span>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<span class="px-2 py-1 text-xs rounded-md font-medium bg-[#EB3C3C1A] text-[#EB3C3C]">
|
||
{{ item.signalDesc || '主体存在失信记录' }}
|
||
</span>
|
||
<div class="flex items-center text-xs text-gray-500">
|
||
<span class="mr-1">
|
||
{{ isExpanded('sx', index) ? '收起详情' : '展开详情' }}
|
||
</span>
|
||
<img src="@/assets/images/report/zk.png" alt="展开" class="w-4 h-4"
|
||
:class="{ 'rotate-180': isExpanded('sx', index) }" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-3 overflow-hidden transition-all duration-300 ease-in-out" :class="{
|
||
'max-h-0 opacity-0': !isExpanded('sx', index),
|
||
'max-h-[500px] opacity-100': isExpanded('sx', index),
|
||
}">
|
||
<div class="border-t border-dashed border-gray-200 pt-3 pb-2 text-xs">
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">被执行人</span>
|
||
<span class="flex-1 text-gray-800">
|
||
{{ item.iname || '-' }}
|
||
<span v-if="item.sexname || item.age" class="text-gray-500 ml-1">
|
||
({{ [item.sexname, item.age && item.age + '岁'].filter(Boolean).join(',') }})
|
||
</span>
|
||
</span>
|
||
</div>
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">地域</span>
|
||
<span class="flex-1 text-gray-800">{{ item.areaname || '-' }}</span>
|
||
</div>
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">法院</span>
|
||
<span class="flex-1 text-gray-800">{{ item.courtname || '-' }}</span>
|
||
</div>
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">执行依据</span>
|
||
<span class="flex-1 text-gray-800">{{ item.gistcid || '-' }}</span>
|
||
</div>
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">立案时间</span>
|
||
<span class="flex-1 text-gray-800">{{ item.regdate || '-' }}</span>
|
||
</div>
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">发布日期</span>
|
||
<span class="flex-1 text-gray-800">{{ item.publishdate || '-' }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 限高记录 -->
|
||
<div v-if="xgList.length" class="px-4 mb-4">
|
||
<LTitle title="限高被执行人记录" />
|
||
<div class="space-y-3">
|
||
<div v-for="(item, index) in xgList" :key="'xg_' + index" class="case-wrapper">
|
||
<div class="bg-white rounded-xl overflow-hidden border px-4 pt-3 border-[#DDDDDD]">
|
||
<div class="cursor-pointer relative" @click="toggleExpand('xg', index)">
|
||
<div class="flex items-center">
|
||
<div class="font-bold text-base text-[#333333] mr-2">
|
||
{{ item.casecode || '暂无案号' }}
|
||
</div>
|
||
<span class="px-2 py-1 text-xs rounded-md font-medium bg-[#F9ECEC] text-[#EB3C3C]">
|
||
{{ item.datatype || '限高被执行人' }}
|
||
</span>
|
||
</div>
|
||
<div class="pb-2 text-sm">
|
||
<span class="text-[#666666]">立案:</span>
|
||
<span class="text-[#333333]">{{ item.regdate || '-' }}</span>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<span class="px-2 py-1 text-xs rounded-md font-medium bg-[#D6943E1A] text-[#D6943E]">
|
||
{{ item.signalDesc || '主体被限制高消费' }}
|
||
</span>
|
||
<div class="flex items-center text-xs text-gray-500">
|
||
<span class="mr-1">
|
||
{{ isExpanded('xg', index) ? '收起详情' : '展开详情' }}
|
||
</span>
|
||
<img src="@/assets/images/report/zk.png" alt="展开" class="w-4 h-4"
|
||
:class="{ 'rotate-180': isExpanded('xg', index) }" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-3 overflow-hidden transition-all duration-300 ease-in-out" :class="{
|
||
'max-h-0 opacity-0': !isExpanded('xg', index),
|
||
'max-h-[500px] opacity-100': isExpanded('xg', index),
|
||
}">
|
||
<div class="border-t border-dashed border-gray-200 pt-3 pb-2 text-xs">
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">被执行人</span>
|
||
<span class="flex-1 text-gray-800">
|
||
{{ item.iname || '-' }}
|
||
<span v-if="item.sexname || item.age" class="text-gray-500 ml-1">
|
||
({{ [item.sexname, item.age && item.age + '岁'].filter(Boolean).join(',') }})
|
||
</span>
|
||
</span>
|
||
</div>
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">地域</span>
|
||
<span class="flex-1 text-gray-800">{{ item.areaname || '-' }}</span>
|
||
</div>
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">法院</span>
|
||
<span class="flex-1 text-gray-800">{{ item.courtname || '-' }}</span>
|
||
</div>
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">立案时间</span>
|
||
<span class="flex-1 text-gray-800">{{ item.regdate || '-' }}</span>
|
||
</div>
|
||
<div class="flex mb-1">
|
||
<span class="w-16 text-gray-500">发布日期</span>
|
||
<span class="flex-1 text-gray-800">{{ item.publishdate || '-' }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="!sxList.length && !xgList.length"
|
||
class="text-gray-500 py-10 text-center bg-gray-50 rounded-lg mx-4 mb-4">
|
||
<div class="text-gray-300 text-3xl mb-2">⚖️</div>
|
||
暂未命中失信或限高被执行人记录
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed, ref, watchEffect } from 'vue'
|
||
import LTitle from '@/components/LTitle.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 raw = computed(() => props.data || {})
|
||
|
||
const finalDecision = computed(() => raw.value.Rule_final_decision || '')
|
||
const finalWeight = computed(() => raw.value.Rule_final_weight || '')
|
||
|
||
const finalDecisionText = computed(() => {
|
||
const v = finalDecision.value
|
||
if (!v) return '未知'
|
||
if (v.toLowerCase() === 'accept') return '通过'
|
||
if (v.toLowerCase() === 'reject') return '拒绝'
|
||
return v
|
||
})
|
||
|
||
// 解析失信记录(el_sx1_*)
|
||
const sxList = computed(() => {
|
||
const d = raw.value
|
||
const list = []
|
||
if (d.el_sx1_datatype) {
|
||
list.push({
|
||
datatype: d.el_sx1_datatype,
|
||
age: d.el_sx1_age,
|
||
areaname: d.el_sx1_areaname,
|
||
casecode: d.el_sx1_casecode,
|
||
courtname: d.el_sx1_courtname,
|
||
gistcid: d.el_sx1_gistcid,
|
||
iname: d.el_sx1_iname,
|
||
partytypename: d.el_sx1_partytypename,
|
||
publishdate: d.el_sx1_publishdate,
|
||
regdate: d.el_sx1_regdate,
|
||
sexname: d.el_sx1_sexname,
|
||
sign: d.el_sx1_sign,
|
||
signalDesc: d.el_sx1_signalDesc,
|
||
signalRating: d.el_sx1_signalRating,
|
||
})
|
||
}
|
||
return list
|
||
})
|
||
|
||
// 解析限高记录(el_xg1_* / el_xg2_* / el_xg3_*)
|
||
const xgList = computed(() => {
|
||
const d = raw.value
|
||
const result = []
|
||
;[1, 2, 3].forEach((n) => {
|
||
const prefix = `el_xg${n}_`
|
||
const datatype = d[`${prefix}datatype`]
|
||
if (!datatype) return
|
||
result.push({
|
||
datatype,
|
||
age: d[`${prefix}age`],
|
||
areaname: d[`${prefix}areaname`],
|
||
casecode: d[`${prefix}casecode`],
|
||
courtname: d[`${prefix}courtname`],
|
||
iname: d[`${prefix}iname`],
|
||
publishdate: d[`${prefix}publishdate`],
|
||
regdate: d[`${prefix}regdate`],
|
||
sexname: d[`${prefix}sexname`],
|
||
sign: d[`${prefix}sign`],
|
||
signalDesc: d[`${prefix}signalDesc`],
|
||
signalRating: d[`${prefix}signalRating`],
|
||
})
|
||
})
|
||
return result
|
||
})
|
||
|
||
const recentLimitDesc = computed(() => {
|
||
if (!xgList.value.length) return '暂无限高记录'
|
||
const recent = xgList.value[0]
|
||
return recent.signalDesc || '主体存在限高被执行人记录'
|
||
})
|
||
|
||
// 展开状态
|
||
const expandedMap = ref({})
|
||
const keyOf = (type, index) => `${type}_${index}`
|
||
const toggleExpand = (type, index) => {
|
||
const k = keyOf(type, index)
|
||
expandedMap.value[k] = !expandedMap.value[k]
|
||
}
|
||
const isExpanded = (type, index) => !!expandedMap.value[keyOf(type, index)]
|
||
|
||
// 上报风险:只要有失信或限高记录即视为有风险
|
||
watchEffect(() => {
|
||
if (!props.notifyRiskStatus) return
|
||
const hasRisk = sxList.value.length > 0 || xgList.value.length > 0
|
||
props.notifyRiskStatus(props.apiId || 'FLXG3A9B', props.index || 0, {
|
||
hasRisk,
|
||
})
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.card {
|
||
padding: 0.5rem;
|
||
}
|
||
|
||
.case-wrapper {
|
||
width: 100%;
|
||
}
|
||
</style>
|