Merge branch 'main' of http://1.117.67.95:3000/team/tydata-webview-v2
This commit is contained in:
404
report-viewer/src/ui/FLXG7E8F/components/CaseDetail.vue
Normal file
404
report-viewer/src/ui/FLXG7E8F/components/CaseDetail.vue
Normal file
@@ -0,0 +1,404 @@
|
||||
<template>
|
||||
<div class="px-4 pb-4">
|
||||
<div class="grid grid-cols-[max-content_1fr] gap-x-2 gap-y-3">
|
||||
<!-- 经办法院/执行法院 -->
|
||||
<span class="text-base text-[#666666]">{{ isSpecialCase ? '执行法院' : '经办法院' }}:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jbfy || caseData.executiveCourt || "—" }}</span>
|
||||
|
||||
<!-- 所属地域 -->
|
||||
<span class="text-base text-[#666666]">所属地域:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_ssdy || caseData.province || "—" }}</span>
|
||||
|
||||
<!-- 案件类型 -->
|
||||
<template v-if="caseData.n_ajlx">
|
||||
<span class="text-base text-[#666666]">案件类型:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_ajlx || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 案号 -->
|
||||
<template v-if="caseData.c_ah">
|
||||
<span class="text-base text-[#666666]">案号:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_ah || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 原审案号 -->
|
||||
<template v-if="caseData.c_ah_ys">
|
||||
<span class="text-base text-[#666666]">原审案号:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_ah_ys || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 后续案号 -->
|
||||
<template v-if="caseData.c_ah_hx">
|
||||
<span class="text-base text-[#666666]">后续案号:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_ah_hx || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 立案时间 -->
|
||||
<template v-if="caseData.d_larq || caseData.fileDate || caseData.larq">
|
||||
<span class="text-base text-[#666666]">立案时间:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.d_larq || caseData.fileDate || caseData.larq) }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 立案案由 -->
|
||||
<template v-if="caseData.n_laay_tree || caseData.n_laay">
|
||||
<span class="text-base text-[#666666]">立案案由:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_laay_tree || caseData.n_laay || "暂无" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 立案案由标签 -->
|
||||
<template v-if="caseData.n_laay_tag">
|
||||
<span class="text-base text-[#666666]">立案案由标签:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_laay_tag || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 当事人信息 -->
|
||||
<template v-if="caseData.c_dsrxx && caseData.c_dsrxx.length > 0">
|
||||
<span class="text-base text-[#666666]">当事人信息:</span>
|
||||
<span class="text-base font-medium text-[#333333]">
|
||||
<span v-for="(party, partyIndex) in caseData.c_dsrxx" :key="partyIndex">
|
||||
{{ party.n_ssdw || "其他" }}: {{ party.c_mc }}<span v-if="partyIndex < caseData.c_dsrxx.length - 1">; </span>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<!-- 失信被执行人特有字段 -->
|
||||
<template v-if="caseType === 'breachCase'">
|
||||
<!-- 案号 -->
|
||||
<template v-if="caseData.caseNumber">
|
||||
<span class="text-base text-[#666666]">案号:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.caseNumber || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 发布日期 -->
|
||||
<template v-if="caseData.issueDate">
|
||||
<span class="text-base text-[#666666]">发布日期:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.issueDate) }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 性别 -->
|
||||
<template v-if="caseData.sex">
|
||||
<span class="text-base text-[#666666]">性别:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.sex || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 履行情况 -->
|
||||
<template v-if="caseData.fulfillStatus">
|
||||
<span class="text-base text-[#666666]">履行情况:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.fulfillStatus || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 判决金额估计 -->
|
||||
<template v-if="caseData.estimatedJudgementAmount">
|
||||
<span class="text-base text-[#666666]">判决金额估计:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.estimatedJudgementAmount) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 失信被执行人行为具体情形 -->
|
||||
<template v-if="caseData.concreteDetails">
|
||||
<span class="text-base text-[#666666]">行为具体情形:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.concreteDetails || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 生效法律文书确定的义务 -->
|
||||
<template v-if="caseData.obligation">
|
||||
<span class="text-base text-[#666666]">生效法律文书确定的义务:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.obligation || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 执行依据单位 -->
|
||||
<template v-if="caseData.enforcementBasisOrganization">
|
||||
<span class="text-base text-[#666666]">执行依据单位:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.enforcementBasisOrganization || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 执行依据文号 -->
|
||||
<template v-if="caseData.enforcementBasisNumber">
|
||||
<span class="text-base text-[#666666]">执行依据文号:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.enforcementBasisNumber || "—" }}</span>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 限制消费被执行人特有字段 -->
|
||||
<template v-if="caseType === 'consumptionRestriction'">
|
||||
<!-- 案件编号 -->
|
||||
<template v-if="caseData.caseNumber">
|
||||
<span class="text-base text-[#666666]">案件编号:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.caseNumber || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 发布日期 -->
|
||||
<template v-if="caseData.issueDate">
|
||||
<span class="text-base text-[#666666]">发布日期:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.issueDate) }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 立案时间 -->
|
||||
<template v-if="caseData.fileDate">
|
||||
<span class="text-base text-[#666666]">立案时间:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.fileDate) }}</span>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 刑事案件特有字段 -->
|
||||
<template v-if="caseType === 'criminal'">
|
||||
<!-- 定罪罪名 -->
|
||||
<template v-if="caseData.n_dzzm">
|
||||
<span class="text-base text-[#666666]">定罪罪名:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_dzzm || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 定罪罪名详细 -->
|
||||
<template v-if="caseData.n_dzzm_tree">
|
||||
<span class="text-base text-[#666666]">定罪罪名详细:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_dzzm_tree || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 判处结果 -->
|
||||
<template v-if="caseData.n_pcjg">
|
||||
<span class="text-base text-[#666666]">判处结果:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_pcjg || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 犯罪金额 -->
|
||||
<template v-if="caseData.n_fzje">
|
||||
<span class="text-base text-[#666666]">犯罪金额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_fzje) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 被请求赔偿金额 -->
|
||||
<template v-if="caseData.n_bqqpcje">
|
||||
<span class="text-base text-[#666666]">被请求赔偿金额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_bqqpcje) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 财产刑执行金额 -->
|
||||
<template v-if="caseData.n_ccxzxje">
|
||||
<span class="text-base text-[#666666]">财产刑执行金额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_ccxzxje) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 财产刑执行金额估计 -->
|
||||
<template v-if="caseData.n_ccxzxje_gj">
|
||||
<span class="text-base text-[#666666]">财产刑执行金额估计:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_ccxzxje_gj) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 判处赔偿金额 -->
|
||||
<template v-if="caseData.n_pcpcje">
|
||||
<span class="text-base text-[#666666]">判处赔偿金额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_pcpcje) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 判处赔偿金额估计 -->
|
||||
<template v-if="caseData.n_pcpcje_gj">
|
||||
<span class="text-base text-[#666666]">判处赔偿金额估计:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_pcpcje_gj) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 被请求赔偿金额估计 -->
|
||||
<template v-if="caseData.n_bqqpcje_gj">
|
||||
<span class="text-base text-[#666666]">被请求赔偿金额估计:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_bqqpcje_gj) || "—" }}</span>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 执行案件特有字段 -->
|
||||
<template v-if="caseType === 'implement'">
|
||||
<!-- 申请执行标的金额 -->
|
||||
<template v-if="caseData.n_sqzxbdje">
|
||||
<span class="text-base text-[#666666]">申请执行标的金额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_sqzxbdje) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 实际到位金额 -->
|
||||
<template v-if="caseData.n_sjdwje !== undefined">
|
||||
<span class="text-base text-[#666666]">实际到位金额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_sjdwje) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 未执行金额 -->
|
||||
<template v-if="caseData.n_wzxje !== undefined">
|
||||
<span class="text-base text-[#666666]">未执行金额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_wzxje) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 相关案件号 -->
|
||||
<template v-if="caseData.c_gkws_glah">
|
||||
<span class="text-base text-[#666666]">相关案件号:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_gkws_glah || "—" }}</span>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 非诉保全审查案件特有字段 -->
|
||||
<template v-if="caseType === 'preservation'">
|
||||
<!-- 申请保全数额 -->
|
||||
<template v-if="caseData.n_sqbqse">
|
||||
<span class="text-base text-[#666666]">申请保全数额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_sqbqse) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 申请保全标的物 -->
|
||||
<template v-if="caseData.c_sqbqbdw">
|
||||
<span class="text-base text-[#666666]">申请保全标的物:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_sqbqbdw || "—" }}</span>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 案件通用字段 -->
|
||||
<!-- 诉讼地位 -->
|
||||
<template v-if="caseData.n_ssdw">
|
||||
<span class="text-base text-[#666666]">诉讼地位:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_ssdw || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 一审诉讼地位 -->
|
||||
<template v-if="caseData.n_ssdw_ys">
|
||||
<span class="text-base text-[#666666]">一审诉讼地位:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_ssdw_ys || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 案件进展阶段 -->
|
||||
<template v-if="caseData.n_ajjzjd">
|
||||
<span class="text-base text-[#666666]">案件进展阶段:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_ajjzjd || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 审理程序 -->
|
||||
<template v-if="caseData.n_slcx">
|
||||
<span class="text-base text-[#666666]">审理程序:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_slcx || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 法院所属层级 -->
|
||||
<template v-if="caseData.n_jbfy_cj">
|
||||
<span class="text-base text-[#666666]">法院所属层级:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jbfy_cj || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 起诉标的金额 -->
|
||||
<template v-if="caseData.n_qsbdje">
|
||||
<span class="text-base text-[#666666]">起诉标的金额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_qsbdje) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 起诉标的金额估计 -->
|
||||
<template v-if="caseData.n_qsbdje_gj">
|
||||
<span class="text-base text-[#666666]">起诉标的金额估计:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_qsbdje_gj) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 结案标的金额 -->
|
||||
<template v-if="caseData.n_jabdje">
|
||||
<span class="text-base text-[#666666]">结案标的金额:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_jabdje) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 结案标的金额估计 -->
|
||||
<template v-if="caseData.n_jabdje_gj">
|
||||
<span class="text-base text-[#666666]">结案标的金额估计:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_jabdje_gj) || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 结案案由 -->
|
||||
<template v-if="caseData.n_jaay_tree || caseData.n_jaay">
|
||||
<span class="text-base text-[#666666]">结案案由:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jaay_tree || caseData.n_jaay || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 结案案由标签 -->
|
||||
<template v-if="caseData.n_jaay_tag">
|
||||
<span class="text-base text-[#666666]">结案案由标签:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jaay_tag || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 结案方式 -->
|
||||
<template v-if="caseData.n_jafs">
|
||||
<span class="text-base text-[#666666]">结案方式:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jafs || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 结案时间 -->
|
||||
<template v-if="caseData.d_jarq">
|
||||
<span class="text-base text-[#666666]">结案时间:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.d_jarq) }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 胜诉估计 -->
|
||||
<template v-if="caseData.n_pj_victory">
|
||||
<span class="text-base text-[#666666]">胜诉估计:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.n_pj_victory || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 公开文书ID -->
|
||||
<template v-if="caseData.c_gkws_id">
|
||||
<span class="text-base text-[#666666]">公开文书ID:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_gkws_id || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 相关当事人 -->
|
||||
<template v-if="caseData.c_gkws_dsr">
|
||||
<span class="text-base text-[#666666]">相关当事人:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_gkws_dsr || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 判决结果 -->
|
||||
<template v-if="caseData.c_gkws_pjjg">
|
||||
<span class="text-base text-[#666666]">判决结果:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_gkws_pjjg || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 审理方式信息 -->
|
||||
<template v-if="caseData.c_slfsxx">
|
||||
<span class="text-base text-[#666666]">审理方式信息:</span>
|
||||
<span class="text-base font-medium text-[#333333]">{{ caseData.c_slfsxx || "—" }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 后续案件信息 -->
|
||||
<template v-if="caseData.next">
|
||||
<span class="text-base text-[#666666]">后续案件:</span>
|
||||
<span class="text-base font-medium text-[#333333]">
|
||||
{{ caseData.next.c_ah }}
|
||||
<span v-if="caseData.next.stage_type" class="ml-2 text-sm px-2 py-0.5 rounded bg-[#EB3C3C1A] text-[#EB3C3C]">
|
||||
{{
|
||||
caseData.next.stage_type === 2
|
||||
? "二审"
|
||||
: caseData.next.stage_type === 3
|
||||
? "再审"
|
||||
: caseData.next.stage_type === 4
|
||||
? "申请再审"
|
||||
: caseData.next.stage_type === 5
|
||||
? "执行"
|
||||
: "其他"
|
||||
}}
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { formatDate, formatLawsuitMoney } from '../utils/lawsuitUtils.js'
|
||||
|
||||
const props = defineProps({
|
||||
caseData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
typeColor: {
|
||||
type: String,
|
||||
default: 'text-blue-600 bg-blue-50'
|
||||
},
|
||||
caseType: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 判断是否为特殊案件类型(失信被执行人、限高被执行人)
|
||||
const isSpecialCase = computed(() => {
|
||||
return props.caseType === 'breachCase' || props.caseType === 'consumptionRestriction'
|
||||
})
|
||||
</script>
|
||||
|
||||
285
report-viewer/src/ui/FLXG7E8F/components/StatisticsOverview.vue
Normal file
285
report-viewer/src/ui/FLXG7E8F/components/StatisticsOverview.vue
Normal file
@@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<div class="">
|
||||
<!-- 概览标题 -->
|
||||
<div class="p-4">
|
||||
<!-- 添加风险概览总结 -->
|
||||
<div class="p-4 rounded-lg" :class="getRiskOverviewClass()">
|
||||
<div class="flex items-center">
|
||||
<div class="w-12 h-12 mr-3 flex-shrink-0">
|
||||
<img :src="getRiskIcon()" alt="风险" class="w-12 h-12 object-contain" />
|
||||
</div>
|
||||
<div class=" text-gray-700">
|
||||
{{ totalCases }}
|
||||
起涉诉案件中,
|
||||
<span v-if="stats.highRiskItems > 0" class="text-orange-600 font-medium">
|
||||
{{ stats.highRiskItems }}
|
||||
</span>
|
||||
<span v-else class="text-green-600 font-medium">0</span>
|
||||
起高风险案件
|
||||
<span v-if="stats.caseTypes.length > 0" class="ml-1">
|
||||
,涉及 {{ stats.caseTypes.length }} 种案件类型
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主要风险指标 -->
|
||||
<div class="grid grid-cols-2 gap-3 p-4">
|
||||
<!-- 风险事项卡片 -->
|
||||
<div class="p-4 bg-[#EB3C3C1A] border border-[#EB3C3C4D] rounded-xl text-center">
|
||||
<div class="text-2xl font-bold text-[#EB3C3C] mb-1">{{ stats.totalRiskItems || 0 }}项</div>
|
||||
<div class="text-sm font-medium text-gray-800 mb-1">风险事项</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
平均{{ stats.totalRiskItems && totalCases > 0 ?
|
||||
(stats.totalRiskItems / totalCases).toFixed(1) :
|
||||
'0.0'
|
||||
}}项/案件
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 高风险案件卡片 -->
|
||||
<div class="p-4 bg-[#EB3C3C1A] border border-[#EB3C3C4D] rounded-xl text-center">
|
||||
<div class="text-2xl font-bold text-[#EB3C3C] mb-1">{{ stats.highRiskItems || 0 }}家</div>
|
||||
<div class="text-sm font-medium text-gray-800 mb-1">高风险案件</div>
|
||||
<div class="text-sm text-gray-500 mb-1">
|
||||
占比{{ totalCases > 0 && stats ?
|
||||
((stats.highRiskItems /
|
||||
totalCases) * 100).toFixed(1) : '0.0' }}%
|
||||
</div>
|
||||
<div class="text-sm text-orange-600">
|
||||
<span class="mr-3">失信{{ stats.breachCaseCount || 0 }}</span>
|
||||
<span style="color: #D6943E;">限高{{ stats.consumptionRestrictionCount || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已结案件卡片 -->
|
||||
<div class="p-4 bg-[#2B79EE1A] border border-[#2B79EE4D] rounded-xl text-center">
|
||||
<div class="text-2xl font-bold text-[#2B79EE] mb-1">{{ stats.closedCases || 0 }}家</div>
|
||||
<div class="text-sm font-medium text-gray-800 mb-1">已结案件</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
占比{{ totalCases > 0 && stats ?
|
||||
Math.round((stats.closedCases / totalCases) * 100) :
|
||||
0
|
||||
}}%
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 案件类型卡片 -->
|
||||
<div class="p-4 bg-[#2B79EE1A] border border-[#2B79EE4D] rounded-xl text-center">
|
||||
<div class="text-2xl font-bold text-[#2B79EE] mb-1">{{ stats.caseTypes.length || 0 }}家</div>
|
||||
<div class="text-sm font-medium text-gray-800 mb-1">案件类型</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
涉及多种类型
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
|
||||
<!-- 案件类型分布 -->
|
||||
<LTitle title="案件类型分布" />
|
||||
<div class="h-[300px] px-4">
|
||||
<v-chart :option="caseTypeChartOption" autoresize />
|
||||
</div>
|
||||
|
||||
<!-- 风险等级分布 -->
|
||||
<LTitle title="风险等级分布" />
|
||||
<div class="bg-[#F9ECEC] border border-[#F0CACA] rounded-xl mx-4 p-4">
|
||||
<div class="grid grid-cols-3 gap-4 text-center">
|
||||
<!-- 高风险案件 -->
|
||||
<div>
|
||||
<div class="text-sm text-gray-600 mb-1">高风险案件</div>
|
||||
<div class="text-xl font-bold text-[#EB3C3C]">{{ stats.highRiskItems || 0 }}条</div>
|
||||
</div>
|
||||
<!-- 中风险案件 -->
|
||||
<div>
|
||||
<div class="text-sm text-gray-600 mb-1">中风险案件</div>
|
||||
<div class="text-xl font-bold text-[#EB3C3C]">{{ stats.mediumRiskItems || 0 }}条</div>
|
||||
</div>
|
||||
<!-- 低风险案件 -->
|
||||
<div>
|
||||
<div class="text-sm text-gray-600 mb-1">低风险案件</div>
|
||||
<div class="text-xl font-bold text-[#D6943E]">{{ stats.lowRiskItems || 0 }}条</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { use } from 'echarts/core'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
import { BarChart } from 'echarts/charts'
|
||||
import { GridComponent, TooltipComponent, TitleComponent, LegendComponent } from 'echarts/components'
|
||||
import VChart from 'vue-echarts'
|
||||
import LTitle from '@/components/LTitle.vue'
|
||||
import { lawsuitTypeMap, getCaseTypeText, getCaseTypeDarkColor } from '../utils/lawsuitUtils.js'
|
||||
|
||||
// 注册必须的组件
|
||||
use([CanvasRenderer, BarChart, GridComponent, TooltipComponent, TitleComponent, LegendComponent])
|
||||
|
||||
const props = defineProps({
|
||||
stats: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
totalCases: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 案件类型分布横向柱状图配置
|
||||
const caseTypeChartOption = computed(() => {
|
||||
// 获取所有可能的案件类型,确保即使没有数据的类型也会显示
|
||||
const allCaseTypes = Object.keys(lawsuitTypeMap).map(key => ({
|
||||
type: key,
|
||||
name: lawsuitTypeMap[key].text,
|
||||
color: lawsuitTypeMap[key].color,
|
||||
darkColor: lawsuitTypeMap[key].darkColor,
|
||||
count: 0, // 默认为0
|
||||
}))
|
||||
|
||||
// 如果有统计数据,更新数量
|
||||
if (props.stats && props.stats.caseTypes && props.stats.caseTypes.length > 0) {
|
||||
// 用实际数据更新默认值
|
||||
props.stats.caseTypes.forEach(item => {
|
||||
const existingType = allCaseTypes.find(type => type.type === item.type)
|
||||
if (existingType) {
|
||||
existingType.count = item.count
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 如果没有任何数据,显示暂无数据的信息
|
||||
return {
|
||||
title: {
|
||||
text: '暂无数据',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
fontWeight: 'normal',
|
||||
color: '#aaa',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// 准备横向柱状图数据 - 不过滤,显示所有类型
|
||||
const categories = allCaseTypes.map(item => item.name)
|
||||
const values = allCaseTypes.map(item => item.count)
|
||||
|
||||
return {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (params) {
|
||||
const dataIndex = params[0].dataIndex
|
||||
return `${categories[dataIndex]}: ${values[dataIndex]}件`
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
left: '0%',
|
||||
right: '5%',
|
||||
bottom: '5%',
|
||||
top: '5%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: function (value) {
|
||||
// 如果最大值是0,设置一个最小值让柱子能显示
|
||||
return Math.max(value.max, 1)
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
color: '#f0f0f0',
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: 12,
|
||||
color: '#666',
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#ddd',
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: categories,
|
||||
axisLabel: {
|
||||
fontSize: 12,
|
||||
color: '#666',
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#ddd',
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '案件数量',
|
||||
type: 'bar',
|
||||
barWidth: '30%',
|
||||
data: values.map((value) => {
|
||||
return {
|
||||
value: value === 0 ? 0.1 : value, // 0值显示为0.1,让柱子能显示一个小尖尖
|
||||
itemStyle: {
|
||||
color: '#5d7eeb',
|
||||
borderRadius: [0, 4, 4, 0],
|
||||
},
|
||||
}
|
||||
}),
|
||||
label: {
|
||||
show: true,
|
||||
position: 'right',
|
||||
fontSize: 12,
|
||||
color: '#666',
|
||||
formatter: function (params) {
|
||||
// 如果是0.1(实际为0),显示为0
|
||||
return params.value === 0.1 ? '0' : params.value
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
|
||||
// 获取风险概览样式
|
||||
const getRiskOverviewClass = () => {
|
||||
// 有高风险案件 - 红色警告
|
||||
if (props.stats.highRiskItems > 0) {
|
||||
return 'bg-[#F9ECEC] border border-[#F0CACA]'
|
||||
}
|
||||
// 有案件但无高风险 - 黄色警示
|
||||
if (props.totalCases > 0) {
|
||||
return 'bg-[#FFF8E1] border border-[#FFE082]'
|
||||
}
|
||||
// 无案件 - 绿色正常
|
||||
return 'bg-[#ECF9EF] border border-[#CAECD3]'
|
||||
}
|
||||
|
||||
// 获取风险图标
|
||||
const getRiskIcon = () => {
|
||||
// 有高风险案件 - 高风险图标
|
||||
if (props.stats.highRiskItems > 0) {
|
||||
return new URL('@/assets/images/report/gfx.png', import.meta.url).href
|
||||
}
|
||||
// 有案件但无高风险 - 中风险图标
|
||||
if (props.totalCases > 0) {
|
||||
return new URL('@/assets/images/report/zfx.png', import.meta.url).href
|
||||
}
|
||||
// 无案件 - 正常图标
|
||||
return new URL('@/assets/images/report/zq.png', import.meta.url).href
|
||||
}
|
||||
</script>
|
||||
|
||||
457
report-viewer/src/ui/FLXG7E8F/index.vue
Normal file
457
report-viewer/src/ui/FLXG7E8F/index.vue
Normal file
@@ -0,0 +1,457 @@
|
||||
<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/ssfxfx.png" alt="个人涉诉风险" class="w-8 h-8 object-contain" />
|
||||
</div>
|
||||
<span class="font-bold text-gray-800">个人涉诉风险分析</span>
|
||||
</div>
|
||||
<LTitle title="涉诉风险整体概览" />
|
||||
<!-- 全局风险概览面板 -->
|
||||
<StatisticsOverview class="" v-if="totalCases > 0 && lawsuitStats" :stats="lawsuitStats"
|
||||
:total-cases="totalCases" />
|
||||
|
||||
<!-- 案件类型筛选tab -->
|
||||
<div v-if="totalCases > 0" class="p-4">
|
||||
<van-tabs v-model:active="activeCaseTypeFilter" line-width="30px" swipeable class="lawsuit-tabs">
|
||||
<!-- 全部风险 -->
|
||||
<van-tab name="all">
|
||||
<template #title>
|
||||
<div class="flex items-center gap-1">
|
||||
<span>全部风险</span>
|
||||
<span>({{ caseTypeCounts.all }})</span>
|
||||
</div>
|
||||
</template>
|
||||
</van-tab>
|
||||
|
||||
<!-- 各类型案件 - 使用v-for渲染 -->
|
||||
<van-tab v-for="(typeInfo, type) in lawsuitTypeMap" :key="type" :name="type">
|
||||
<template #title>
|
||||
<div class="flex items-center gap-1">
|
||||
<span>{{ typeInfo.text }}({{ caseTypeCounts[type] || 0 }})</span>
|
||||
</div>
|
||||
</template>
|
||||
<div v-if="filteredCases.length === 0" class="p-8 text-center text-gray-500">
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<van-empty :description="`暂无${typeInfo.text}记录`" />
|
||||
</div>
|
||||
</div>
|
||||
</van-tab>
|
||||
</van-tabs>
|
||||
</div>
|
||||
|
||||
<!-- 案件列表 -->
|
||||
<div v-if="filteredCases.length > 0" class="space-y-3 px-4 mb-4">
|
||||
<div v-for="(caseItem, index) in filteredCases" :key="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="toggleCaseExpand(caseItem.id || index, 'case', index)">
|
||||
<!-- 顶部区域:案件标题和案件类型 -->
|
||||
<div class=" flex items-center">
|
||||
<!-- 案件标题 -->
|
||||
<div class="font-bold text-base text-[#333333] mr-2">{{ caseItem.c_ah || caseItem.caseNumber || '暂无案号' }}</div>
|
||||
|
||||
<!-- 案件类型标签 -->
|
||||
<span class="px-2 py-1 text-sm rounded-md font-medium bg-[#F9ECEC] text-[#EB3C3C]">
|
||||
{{ getCaseTypeText(caseItem.type) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 中间区域:立案时间 -->
|
||||
<div class="pb-2">
|
||||
<span class="text-sm text-[#666666]">立案:</span>
|
||||
<span class="text-sm text-[#333333]">{{ formatDate(caseItem.d_larq || caseItem.fileDate) }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 底部区域:风险等级和案件状态 -->
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- 风险等级标签 -->
|
||||
<span class="px-2 py-1 text-sm rounded-md font-medium"
|
||||
:class="getCaseTypeRiskLevel(caseItem.type).color">
|
||||
{{ getCaseTypeRiskLevel(caseItem.type).text }}
|
||||
</span>
|
||||
<!-- 案件状态标签 -->
|
||||
<span v-if="caseItem.n_ajjzjd" class="px-2 py-1 text-sm rounded-md font-medium"
|
||||
:class="getCaseStatusClass(caseItem.n_ajjzjd)">
|
||||
{{ caseItem.n_ajjzjd }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 展开指示器 -->
|
||||
<div class="absolute right-4 bottom-3 flex items-center text-sm text-gray-500">
|
||||
<img src="@/assets/images/report/zk.png" alt="展开" class="w-4 h-4 container"
|
||||
:class="{ 'rotate-180': isCaseExpanded(caseItem.id || index, 'case', index) }" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 案件详情抽屉 -->
|
||||
<div class="mt-4 overflow-hidden transition-all duration-300 ease-in-out" :class="{
|
||||
'max-h-0 opacity-0': !isCaseExpanded(caseItem.id || index, 'case', index),
|
||||
'max-h-none opacity-100': isCaseExpanded(caseItem.id || index, 'case', index),
|
||||
}">
|
||||
<div class="mt-1 transform transition-all duration-300">
|
||||
<div class="relative">
|
||||
<CaseDetail :case-data="caseItem" :type-color="getCaseTypeColor(caseItem.type)"
|
||||
:case-type="caseItem.type" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 无涉诉风险时的空状态展示 -->
|
||||
<div v-else 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 { ref, computed, onMounted, watch } from 'vue'
|
||||
import LTitle from '@/components/LTitle.vue'
|
||||
import LRemark from '@/components/LRemark.vue'
|
||||
import StatisticsOverview from './components/StatisticsOverview.vue'
|
||||
import CaseDetail from './components/CaseDetail.vue'
|
||||
import { useRiskNotifier } from '@/composables/useRiskNotifier'
|
||||
import {
|
||||
lawsuitTypeMap,
|
||||
getCaseTypeText,
|
||||
getCaseTypeColor,
|
||||
getRiskLevel,
|
||||
getCaseStatusClass,
|
||||
formatDate,
|
||||
getLawsuitStats,
|
||||
getCaseTypeRiskLevel,
|
||||
} from './utils/lawsuitUtils.js'
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
apiId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
notifyRiskStatus: {
|
||||
type: Function,
|
||||
default: () => { },
|
||||
},
|
||||
})
|
||||
|
||||
// 获取 judicial_data 数据
|
||||
const judicialData = computed(() => {
|
||||
return props.data?.data?.judicial_data || props.data?.judicial_data || {}
|
||||
})
|
||||
|
||||
// 获取 lawsuitStat 数据
|
||||
const lawsuitStat = computed(() => {
|
||||
return judicialData.value.lawsuitStat || {
|
||||
administrative: {},
|
||||
bankrupt: {},
|
||||
cases_tree: { criminal: [], civil: [] },
|
||||
civil: {},
|
||||
count: {},
|
||||
criminal: { cases: [], count: {} },
|
||||
implement: {},
|
||||
preservation: {},
|
||||
}
|
||||
})
|
||||
|
||||
// 获取失信列表
|
||||
const breachCaseList = computed(() => {
|
||||
return judicialData.value.breachCaseList || []
|
||||
})
|
||||
|
||||
// 获取限制消费列表
|
||||
const consumptionRestrictionList = computed(() => {
|
||||
return judicialData.value.consumptionRestrictionList || []
|
||||
})
|
||||
|
||||
// 用于跟踪展开的案件卡片
|
||||
const expandedCases = ref({})
|
||||
|
||||
// 切换展开/收起案件详情
|
||||
const toggleCaseExpand = (caseId, listType, index) => {
|
||||
const uniqueKey = `${caseId}_${listType}_${index}`
|
||||
expandedCases.value[uniqueKey] = !expandedCases.value[uniqueKey]
|
||||
}
|
||||
|
||||
// 检查案件是否展开
|
||||
const isCaseExpanded = (caseId, listType, index) => {
|
||||
const uniqueKey = `${caseId}_${listType}_${index}`
|
||||
return !!expandedCases.value[uniqueKey]
|
||||
}
|
||||
|
||||
// 当前选中的案件类型筛选
|
||||
const activeCaseTypeFilter = ref('all')
|
||||
|
||||
// 计算所有案件数据
|
||||
const allCases = computed(() => {
|
||||
const cases = []
|
||||
|
||||
// 添加失信被执行人案件
|
||||
breachCaseList.value.forEach((item, index) => {
|
||||
cases.push({
|
||||
...item,
|
||||
type: 'breachCase',
|
||||
id: `breachCase_${index}`,
|
||||
// 映射字段以保持兼容性
|
||||
c_ah: item.caseNumber,
|
||||
d_larq: item.fileDate,
|
||||
n_ajjzjd: item.fulfillStatus === '全部未履行' ? '未结案' : '已结案',
|
||||
})
|
||||
})
|
||||
|
||||
// 添加限高被执行人案件
|
||||
consumptionRestrictionList.value.forEach((item, index) => {
|
||||
cases.push({
|
||||
...item,
|
||||
type: 'consumptionRestriction',
|
||||
id: `consumptionRestriction_${index}`,
|
||||
// 映射字段以保持兼容性
|
||||
c_ah: item.caseNumber,
|
||||
d_larq: item.fileDate,
|
||||
n_ajjzjd: '未结案', // 限高案件通常为未结案
|
||||
})
|
||||
})
|
||||
|
||||
// 添加其他类型案件
|
||||
if (lawsuitStat.value) {
|
||||
// 处理民事案件
|
||||
if (lawsuitStat.value.civil && lawsuitStat.value.civil.cases) {
|
||||
lawsuitStat.value.civil.cases.forEach((item, index) => {
|
||||
cases.push({
|
||||
...item,
|
||||
type: 'civil',
|
||||
id: `civil_${index}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 处理刑事案件
|
||||
if (lawsuitStat.value.criminal && lawsuitStat.value.criminal.cases) {
|
||||
lawsuitStat.value.criminal.cases.forEach((item, index) => {
|
||||
cases.push({
|
||||
...item,
|
||||
type: 'criminal',
|
||||
id: `criminal_${index}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 处理执行案件
|
||||
if (lawsuitStat.value.implement && lawsuitStat.value.implement.cases) {
|
||||
lawsuitStat.value.implement.cases.forEach((item, index) => {
|
||||
cases.push({
|
||||
...item,
|
||||
type: 'implement',
|
||||
id: `implement_${index}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 处理行政案件
|
||||
if (lawsuitStat.value.administrative && lawsuitStat.value.administrative.cases) {
|
||||
lawsuitStat.value.administrative.cases.forEach((item, index) => {
|
||||
cases.push({
|
||||
...item,
|
||||
type: 'administrative',
|
||||
id: `administrative_${index}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 处理破产案件
|
||||
if (lawsuitStat.value.bankrupt && lawsuitStat.value.bankrupt.cases) {
|
||||
lawsuitStat.value.bankrupt.cases.forEach((item, index) => {
|
||||
cases.push({
|
||||
...item,
|
||||
type: 'bankrupt',
|
||||
id: `bankrupt_${index}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 处理保全案件
|
||||
if (lawsuitStat.value.preservation && lawsuitStat.value.preservation.cases) {
|
||||
lawsuitStat.value.preservation.cases.forEach((item, index) => {
|
||||
cases.push({
|
||||
...item,
|
||||
type: 'preservation',
|
||||
id: `preservation_${index}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return cases
|
||||
})
|
||||
|
||||
// 计算总案件数
|
||||
const totalCases = computed(() => allCases.value.length)
|
||||
|
||||
// 计算涉诉风险统计
|
||||
const lawsuitStats = computed(() => {
|
||||
if (totalCases.value === 0) return null
|
||||
|
||||
const stats = {
|
||||
totalRiskItems: totalCases.value,
|
||||
highRiskItems: 0,
|
||||
mediumRiskItems: 0,
|
||||
lowRiskItems: 0,
|
||||
breachCaseCount: breachCaseList.value.length,
|
||||
consumptionRestrictionCount: consumptionRestrictionList.value.length,
|
||||
closedCases: 0,
|
||||
caseTypes: [],
|
||||
}
|
||||
|
||||
// 统计各类型案件数量
|
||||
const typeCounts = {}
|
||||
Object.keys(lawsuitTypeMap).forEach(type => {
|
||||
typeCounts[type] = 0
|
||||
})
|
||||
|
||||
allCases.value.forEach(caseItem => {
|
||||
// 根据案件类型统计风险等级
|
||||
const riskLevel = getCaseTypeRiskLevel(caseItem.type).level
|
||||
if (riskLevel === 'high') {
|
||||
stats.highRiskItems++
|
||||
} else if (riskLevel === 'medium') {
|
||||
stats.mediumRiskItems++
|
||||
} else {
|
||||
stats.lowRiskItems++
|
||||
}
|
||||
|
||||
// 统计已结案件
|
||||
if (caseItem.n_ajjzjd && caseItem.n_ajjzjd.includes('已结')) {
|
||||
stats.closedCases++
|
||||
}
|
||||
|
||||
// 统计案件类型
|
||||
if (caseItem.type) {
|
||||
typeCounts[caseItem.type] = (typeCounts[caseItem.type] || 0) + 1
|
||||
}
|
||||
})
|
||||
|
||||
// 转换为数组格式
|
||||
stats.caseTypes = Object.keys(typeCounts)
|
||||
.filter(type => typeCounts[type] > 0)
|
||||
.map(type => ({
|
||||
type,
|
||||
count: typeCounts[type],
|
||||
name: getCaseTypeText(type),
|
||||
color: getCaseTypeColor(type),
|
||||
}))
|
||||
.sort((a, b) => b.count - a.count)
|
||||
|
||||
return stats
|
||||
})
|
||||
|
||||
// 按案件类型筛选案件
|
||||
const filteredCases = computed(() => {
|
||||
if (activeCaseTypeFilter.value === 'all') {
|
||||
return allCases.value
|
||||
}
|
||||
|
||||
return allCases.value.filter(caseItem => caseItem.type === activeCaseTypeFilter.value)
|
||||
})
|
||||
|
||||
// 获取每种案件类型的数量
|
||||
const caseTypeCounts = computed(() => {
|
||||
const counts = {
|
||||
all: totalCases.value,
|
||||
}
|
||||
|
||||
// 初始化所有案件类型的计数
|
||||
Object.keys(lawsuitTypeMap).forEach(type => {
|
||||
counts[type] = 0
|
||||
})
|
||||
|
||||
// 计算每种类型的案件数量
|
||||
allCases.value.forEach(caseItem => {
|
||||
if (caseItem.type) {
|
||||
counts[caseItem.type]++
|
||||
}
|
||||
})
|
||||
|
||||
return counts
|
||||
})
|
||||
|
||||
// 设置当前筛选类型
|
||||
const setCaseTypeFilter = type => {
|
||||
activeCaseTypeFilter.value = type
|
||||
}
|
||||
|
||||
// 计算风险评分(0-100分,分数越高越安全)
|
||||
const riskScore = computed(() => {
|
||||
const cases = totalCases.value;
|
||||
|
||||
// 根据涉诉案件数量计算评分
|
||||
// 0件:100分(最安全)
|
||||
// 1-2件:70分(中等风险)
|
||||
// 3-5件:50分(较高风险)
|
||||
// 6-10件:30分(高风险)
|
||||
// 10件以上:10分(极高风险)
|
||||
if (cases === 0) return 100;
|
||||
if (cases <= 2) return 70;
|
||||
if (cases <= 5) return 50;
|
||||
if (cases <= 10) return 30;
|
||||
return 10;
|
||||
});
|
||||
|
||||
// 使用 composable 通知父组件风险评分
|
||||
useRiskNotifier(props, riskScore);
|
||||
|
||||
// 暴露给父组件
|
||||
defineExpose({
|
||||
riskScore
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.case-wrapper {
|
||||
@apply relative;
|
||||
}
|
||||
|
||||
.lawsuit-tabs :deep(.van-tabs__wrap) {
|
||||
height: 32px !important;
|
||||
background-color: transparent !important;
|
||||
padding: 0 !important;
|
||||
border-bottom: 1px solid #DDDDDD !important;
|
||||
}
|
||||
|
||||
.lawsuit-tabs :deep(.van-tabs__nav) {
|
||||
background-color: transparent !important;
|
||||
gap: 0;
|
||||
height: 32px !important;
|
||||
}
|
||||
|
||||
.lawsuit-tabs :deep(.van-tab) {
|
||||
color: #999999 !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
.lawsuit-tabs :deep(.van-tab--active) {
|
||||
color: var(--van-theme-primary) !important;
|
||||
background-color: unset !important;
|
||||
}
|
||||
|
||||
.lawsuit-tabs :deep(.van-tabs__line) {
|
||||
height: 3px !important;
|
||||
border-radius: 1px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
303
report-viewer/src/ui/FLXG7E8F/utils/lawsuitUtils.js
Normal file
303
report-viewer/src/ui/FLXG7E8F/utils/lawsuitUtils.js
Normal file
@@ -0,0 +1,303 @@
|
||||
// 案件类型映射表
|
||||
export const lawsuitTypeMap = {
|
||||
breachCase: {
|
||||
text: '失信被执行',
|
||||
color: 'text-red-600 bg-red-50',
|
||||
darkColor: 'bg-red-500',
|
||||
riskLevel: 'high', // 高风险
|
||||
},
|
||||
consumptionRestriction: {
|
||||
text: '限高被执行',
|
||||
color: 'text-orange-600 bg-orange-50',
|
||||
darkColor: 'bg-orange-500',
|
||||
riskLevel: 'high', // 高风险
|
||||
},
|
||||
criminal: {
|
||||
text: '刑事案件',
|
||||
color: 'text-red-600 bg-red-50',
|
||||
darkColor: 'bg-red-500',
|
||||
riskLevel: 'high', // 高风险
|
||||
},
|
||||
civil: {
|
||||
text: '民事案件',
|
||||
color: 'text-blue-600 bg-blue-50',
|
||||
darkColor: 'bg-blue-500',
|
||||
riskLevel: 'medium', // 中风险
|
||||
},
|
||||
administrative: {
|
||||
text: '行政案件',
|
||||
color: 'text-purple-600 bg-purple-50',
|
||||
darkColor: 'bg-purple-500',
|
||||
riskLevel: 'medium', // 中风险
|
||||
},
|
||||
implement: {
|
||||
text: '执行案件',
|
||||
color: 'text-orange-600 bg-orange-50',
|
||||
darkColor: 'bg-orange-500',
|
||||
riskLevel: 'medium', // 中风险
|
||||
},
|
||||
bankrupt: {
|
||||
text: '强制清算与破产案件',
|
||||
color: 'text-rose-600 bg-rose-50',
|
||||
darkColor: 'bg-rose-500',
|
||||
riskLevel: 'high', // 高风险
|
||||
},
|
||||
preservation: {
|
||||
text: '非诉保全审查',
|
||||
color: 'text-amber-600 bg-amber-50',
|
||||
darkColor: 'bg-amber-500',
|
||||
riskLevel: 'low', // 低风险
|
||||
},
|
||||
}
|
||||
|
||||
// 案件类型文本
|
||||
export const getCaseTypeText = type => {
|
||||
return lawsuitTypeMap[type]?.text || '其他案件'
|
||||
}
|
||||
|
||||
// 案件类型颜色
|
||||
export const getCaseTypeColor = type => {
|
||||
return lawsuitTypeMap[type]?.color || 'text-gray-600 bg-gray-50'
|
||||
}
|
||||
|
||||
// 案件类型深色
|
||||
export const getCaseTypeDarkColor = type => {
|
||||
return lawsuitTypeMap[type]?.darkColor || 'bg-gray-500'
|
||||
}
|
||||
|
||||
// 格式化日期显示
|
||||
export const formatDate = dateStr => {
|
||||
if (!dateStr) return '—'
|
||||
// 转换YYYY-MM-DD为年月日格式
|
||||
if (dateStr.includes('-')) {
|
||||
const parts = dateStr.split('-')
|
||||
if (parts.length === 3) {
|
||||
return `${parts[0]}年${parts[1]}月${parts[2]}日`
|
||||
}
|
||||
}
|
||||
return dateStr // 如果不是标准格式则返回原始字符串
|
||||
}
|
||||
|
||||
// 格式化金额显示(单位:万元)
|
||||
export const formatLawsuitMoney = money => {
|
||||
if (!money) return '—'
|
||||
|
||||
const value = parseFloat(money)
|
||||
if (isNaN(value)) return '—'
|
||||
|
||||
// 超过1亿显示亿元
|
||||
if (value >= 10000) {
|
||||
return (
|
||||
(value / 10000).toLocaleString('zh-CN', {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 2,
|
||||
}) + ' 亿元'
|
||||
)
|
||||
}
|
||||
|
||||
// 否则显示万元
|
||||
return (
|
||||
value.toLocaleString('zh-CN', {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 2,
|
||||
}) + ' 万元'
|
||||
)
|
||||
}
|
||||
|
||||
// 获取案件状态样式
|
||||
export const getCaseStatusClass = status => {
|
||||
if (!status) return 'bg-gray-100 text-gray-500'
|
||||
|
||||
if (status.includes('已结') || status.includes('已办结')) {
|
||||
return 'bg-green-50 text-green-600'
|
||||
} else if (status.includes('执行中') || status.includes('审理中')) {
|
||||
return 'bg-blue-50 text-blue-600'
|
||||
} else if (status.includes('未执行')) {
|
||||
return 'bg-amber-50 text-amber-600'
|
||||
} else {
|
||||
return 'bg-gray-100 text-gray-500'
|
||||
}
|
||||
}
|
||||
|
||||
// 获取企业状态对应的样式
|
||||
export const getStatusClass = status => {
|
||||
if (!status) return 'bg-gray-100 text-gray-500'
|
||||
|
||||
if (status.includes('注销') || status.includes('吊销')) {
|
||||
return 'bg-red-50 text-red-600'
|
||||
} else if (status.includes('存续') || status.includes('在营')) {
|
||||
return 'bg-green-50 text-green-600'
|
||||
} else if (status.includes('筹建') || status.includes('新设')) {
|
||||
return 'bg-blue-50 text-blue-600'
|
||||
} else {
|
||||
return 'bg-yellow-50 text-yellow-600'
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化资本金额显示
|
||||
export const formatCapital = (capital, currency) => {
|
||||
if (!capital) return '—'
|
||||
|
||||
// 检查是否包含"万"字或需要显示为万元
|
||||
let unit = ''
|
||||
let value = parseFloat(capital)
|
||||
|
||||
// 处理原始数据中可能带有的单位
|
||||
if (typeof capital === 'string' && capital.includes('万')) {
|
||||
unit = '万'
|
||||
// 提取数字部分
|
||||
const numMatch = capital.match(/[\d.]+/)
|
||||
value = numMatch ? parseFloat(numMatch[0]) : 0
|
||||
} else if (value >= 10000) {
|
||||
// 大额数字转换为万元显示
|
||||
value = value / 10000
|
||||
unit = '万'
|
||||
}
|
||||
|
||||
// 格式化数字,保留两位小数(如果有小数部分)
|
||||
const formattedValue = value.toLocaleString('zh-CN', {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 2,
|
||||
})
|
||||
|
||||
return `${formattedValue}${unit} ${currency || '人民币'}`
|
||||
}
|
||||
|
||||
// 获取涉诉风险等级
|
||||
export const getRiskLevel = lawsuitInfo => {
|
||||
if (!lawsuitInfo) {
|
||||
return {
|
||||
level: 'low',
|
||||
text: '低风险',
|
||||
color: 'text-green-600 bg-green-50',
|
||||
}
|
||||
}
|
||||
|
||||
// 失信被执行人是最高风险
|
||||
if (lawsuitInfo.breachCaseList && lawsuitInfo.breachCaseList.length > 0) {
|
||||
return {
|
||||
level: 'high',
|
||||
text: '高风险',
|
||||
color: 'text-red-600 bg-red-50',
|
||||
}
|
||||
}
|
||||
|
||||
// 限高被执行人是最高风险
|
||||
if (lawsuitInfo.consumptionRestrictionList && lawsuitInfo.consumptionRestrictionList.length > 0) {
|
||||
return {
|
||||
level: 'high',
|
||||
text: '高风险',
|
||||
color: 'text-red-600 bg-red-50',
|
||||
}
|
||||
}
|
||||
|
||||
// 有涉诉数据的风险级别
|
||||
if (lawsuitInfo.lawsuitStat && Object.keys(lawsuitInfo.lawsuitStat).length > 0) {
|
||||
// 检查是否有未结案的案件
|
||||
const data = lawsuitInfo.lawsuitStat
|
||||
if (data.count && data.count.count_wei_total && data.count.count_wei_total > 0) {
|
||||
return {
|
||||
level: 'medium',
|
||||
text: '中风险',
|
||||
color: 'text-amber-600 bg-amber-50',
|
||||
}
|
||||
}
|
||||
|
||||
// 只有已结案的为低中风险
|
||||
return {
|
||||
level: 'low-medium',
|
||||
text: '低中风险',
|
||||
color: 'text-yellow-600 bg-yellow-50',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
level: 'low',
|
||||
text: '低风险',
|
||||
color: 'text-green-600 bg-green-50',
|
||||
}
|
||||
}
|
||||
|
||||
// 获取涉诉案件统计
|
||||
export const getLawsuitStats = lawsuitInfo => {
|
||||
if (!lawsuitInfo) return null
|
||||
|
||||
const stats = {
|
||||
total: 0,
|
||||
types: [],
|
||||
}
|
||||
|
||||
// 统计各类型案件数量
|
||||
Object.keys(lawsuitTypeMap).forEach(type => {
|
||||
let count = 0
|
||||
|
||||
if (type === 'breachCase') {
|
||||
count = lawsuitInfo.breachCaseList && lawsuitInfo.breachCaseList.length > 0 ? lawsuitInfo.breachCaseList.length : 0
|
||||
} else if (type === 'consumptionRestriction') {
|
||||
count = lawsuitInfo.consumptionRestrictionList && lawsuitInfo.consumptionRestrictionList.length > 0 ? lawsuitInfo.consumptionRestrictionList.length : 0
|
||||
} else if (lawsuitInfo.lawsuitStat && lawsuitInfo.lawsuitStat[type] && Object.keys(lawsuitInfo.lawsuitStat[type]).length > 0) {
|
||||
const typeData = lawsuitInfo.lawsuitStat[type]
|
||||
count = typeData.cases && typeData.cases.length ? typeData.cases.length : 0
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
stats.total += count
|
||||
stats.types.push({
|
||||
type,
|
||||
count,
|
||||
name: getCaseTypeText(type),
|
||||
color: getCaseTypeColor(type),
|
||||
darkColor: getCaseTypeDarkColor(type),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
// 获取案件类型优先级顺序
|
||||
export const getCaseTypePriority = () => {
|
||||
return [
|
||||
'breachCase', // 失信被执行人(最高风险)
|
||||
'consumptionRestriction', // 限高被执行人
|
||||
'criminal', // 刑事案件
|
||||
'civil', // 民事案件
|
||||
'administrative', // 行政案件
|
||||
'implement', // 执行案件
|
||||
'bankrupt', // 强制清算与破产案件
|
||||
'preservation', // 非诉保全审查
|
||||
]
|
||||
}
|
||||
|
||||
// 根据案件类型获取风险等级
|
||||
export const getCaseTypeRiskLevel = caseType => {
|
||||
const typeInfo = lawsuitTypeMap[caseType]
|
||||
if (!typeInfo) {
|
||||
return {
|
||||
level: 'low',
|
||||
text: '低风险',
|
||||
color: 'text-green-600 bg-green-50',
|
||||
}
|
||||
}
|
||||
|
||||
const riskLevelMap = {
|
||||
high: {
|
||||
text: '高风险',
|
||||
color: 'text-red-600 bg-red-50',
|
||||
},
|
||||
medium: {
|
||||
text: '中风险',
|
||||
color: 'text-amber-600 bg-amber-50',
|
||||
},
|
||||
low: {
|
||||
text: '低风险',
|
||||
color: 'text-green-600 bg-green-50',
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
level: typeInfo.riskLevel,
|
||||
...riskLevelMap[typeInfo.riskLevel],
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user