Files
tydata-webview-v2/report-viewer/src/ui/CQYGL3F8E/components/Lawsuit.vue

1716 lines
80 KiB
Vue
Raw Normal View History

2025-11-13 22:27:54 +08:00
<template>
<!-- 关联企业涉诉风险 -->
<div class="card shadow-sm rounded-xl overflow-hidden p-4">
<div class=" border border-[#EEEEEE] p-4 rounded-xl">
<div class="flex items-center mb-3">
<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 v-if="lawsuitCompanies.length > 0 && allLawsuitStats" class="mb-6">
<div class="">
<!-- 概览标题 -->
<div class="mb-6">
<!-- 添加风险概览总结 -->
<div class="mt-4 p-4 bg-[#FFF8E1] rounded-lg">
<div class="flex items-center">
<div class="w-12 h-12 mr-3">
<img src="@/assets/images/report/zfx.png" alt="风险"
class="w-12 h-12 object-contain" />
</div>
<div class="text-sm text-gray-700">
{{ totalCompanies }}
家关联企业中
<span v-if="allLawsuitStats && allLawsuitStats.totalCompanies > 0"
class="text-orange-600 font-medium">{{ allLawsuitStats.totalCompanies }}</span>
<span v-else class="text-green-600 font-medium">0</span>
家存在涉诉风险
<span v-if="allLawsuitStats && allLawsuitStats.highRiskCompanies > 0"
class="text-red-600">
(高风险: {{ allLawsuitStats.highRiskCompanies }} )
</span>
<span v-if="allLawsuitStats && allLawsuitStats.totalRiskItems > 0" class="ml-1">
{{ allLawsuitStats.totalRiskItems }} 个风险事项
</span>
</div>
</div>
</div>
</div>
<!-- 主要风险指标 -->
<div class="space-y-3 mb-6">
<!-- 风险事项卡片 -->
<div
class="p-4 bg-[#EB3C3C1A] border border-[#EB3C3C4D] rounded-lg flex items-center justify-between">
<div class="flex items-center">
<div class="text-3xl font-bold text-red-600 mr-4">{{ allLawsuitStats?.totalRiskItems ||
0 }}
</div>
<div>
<div class="text-sm font-medium text-gray-800">风险事项</div>
<div class="text-xs text-gray-500">
平均{{ allLawsuitStats && allLawsuitStats.totalCompanies > 0 ?
(allLawsuitStats.totalRiskItems / allLawsuitStats.totalCompanies).toFixed(1) :
'0.0'
}}/企业
</div>
</div>
</div>
</div>
<!-- 风险企业卡片 -->
<div
class="p-4 bg-[#D6943E1A] border border-[#D6943E4D] rounded-lg flex items-center justify-between">
<div class="flex items-center">
<div class="text-3xl font-bold text-orange-600 mr-4">{{ allLawsuitStats?.totalCompanies
|| 0
}}</div>
<div>
<div class="text-sm font-medium text-gray-800">风险企业</div>
<div class="text-xs text-gray-500">
占比关联企业{{ totalCompanies > 0 && allLawsuitStats ?
((allLawsuitStats.totalCompanies /
totalCompanies) * 100).toFixed(1) : '0.0' }}%
</div>
<div class="flex items-center gap-3 mt-1">
<span class="text-xs text-red-600">高风险: {{ allLawsuitStats?.highRiskCompanies ||
0
}}</span>
<span class="text-xs text-amber-600">中风险: {{
allLawsuitStats?.mediumRiskCompanies ||
0 }}</span>
</div>
</div>
</div>
</div>
<!-- 正常经营企业卡片 -->
<div
class="p-4 bg-[#2B79EE1A] border border-[#2B79EE4D] rounded-lg flex items-center justify-between">
<div class="flex items-center">
<div class="text-3xl font-bold text-blue-600 mr-4">{{
allLawsuitStats?.normalOperatingCompanies || 0 }}</div>
<div>
<div class="text-sm font-medium text-gray-800">正常经营企业</div>
<div class="text-xs text-gray-500">
占比{{ totalCompanies > 0 && allLawsuitStats ?
Math.round((allLawsuitStats.normalOperatingCompanies / totalCompanies) * 100) :
0
}}%
</div>
</div>
</div>
</div>
<!-- 吊销注销企业卡片 -->
<div
class="p-4 bg-[#9999991A] border border-[#9999994D] rounded-lg flex items-center justify-between">
<div class="flex items-center">
<div class="text-3xl font-bold text-gray-600 mr-4">{{ allLawsuitStats?.canceledCompanies
||
0 }}</div>
<div>
<div class="text-sm font-medium text-gray-800">吊销注销企业</div>
<div class="text-xs text-gray-500">
占比{{ totalCompanies > 0 && allLawsuitStats ?
Math.round((allLawsuitStats.canceledCompanies / totalCompanies) * 100) : 0 }}%
</div>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<!-- 企业风险分布 -->
<LTitle title="企业风险分布" />
<div class="flex items-center">
<!-- 饼图 -->
<div class="relative w-32 h-32 mx-12">
<v-chart :option="riskDistributionChartOption" class="w-full h-full" autoresize />
</div>
<!-- 图例 -->
<div class="flex-1 space-y-2">
<div class="flex items-center">
<div class="w-3 h-3 rounded-sm mr-2" style="background-color: #EB3C3C;"></div>
<span class="text-xs text-gray-600">高风险</span>
<span class="text-xs font-medium text-gray-800 ml-1">{{
allLawsuitStats?.highRiskCompanies || 0 }}</span>
</div>
<div class="flex items-center">
<div class="w-3 h-3 rounded-sm mr-2" style="background-color: #D6943E;"></div>
<span class="text-xs text-gray-600">中风险</span>
<span class="text-xs font-medium text-gray-800 ml-1">{{
allLawsuitStats?.mediumRiskCompanies || 0 }}</span>
</div>
<div class="flex items-center">
<div class="w-3 h-3 rounded-sm mr-2" style="background-color: #1FBE5D;"></div>
<span class="text-xs text-gray-600">低风险</span>
<span class="text-xs font-medium text-gray-800 ml-1">{{
allLawsuitStats?.lowRiskCompanies || 0 }}</span>
</div>
</div>
</div>
<!-- 案件类型统计 - 横向柱状图 -->
<LTitle title="案件类型分布" />
<div class="h-[300px]">
<v-chart :option="caseTypeChartOption" autoresize />
</div>
</div>
</div>
</div>
<!-- 风险企业一览 -->
<div class="mb-6" v-if="
lawsuitCompanies.length > 0 ||
filteredLawsuitCompanies.length > 0
">
<LTitle title="风险企业一览"></LTitle>
</div>
<!-- 案件类型筛选tab -->
<div v-if="lawsuitCompanies.length > 0" class="mb-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>({{ caseTypeCompanyCounts.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 }}({{ caseTypeCompanyCounts[type] || 0 }})</span>
</div>
</template>
<div v-if="filteredLawsuitCompanies.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="filteredLawsuitCompanies.length > 0" class="space-y-3">
<div v-for="(company, index) in filteredLawsuitCompanies" :key="index"
class="company-wrapper bg-[#F9F9F9] rounded-lg overflow-hidden shadow-sm border border-[#EEEEEE]">
<!-- 企业卡片 - 可点击展开 -->
<div class="cursor-pointer relative"
@click="toggleCompanyExpand(company.orgName, 'lawsuit', index)">
<!-- 顶部区域企业名称和案件统计 -->
<div class="px-4 py-3 flex items-center justify-between">
<!-- 企业名称 -->
<div class="font-medium text-[#333333] truncate">{{ company.orgName }}</div>
<!-- 右侧案件数量和状态 -->
<div class="flex items-center gap-3 flex-shrink-0">
<!-- 案件数量 -->
<div v-if="getLawsuitStats(company)"
class="flex items-center px-2 text-xs rounded-xl font-medium bg-[#EB3C3C1A] text-[#EB3C3C]">
<span class="text-[#EB3C3C] font-medium text-sm">案件:</span>
<span class="text-[#EB3C3C] ml-1">{{ getLawsuitStats(company).total
||
0
}}</span>
</div>
<!-- 企业状态 -->
<span v-if="company.basicInfo && company.basicInfo.regStatus"
class="px-2 py-1 rounded-full text-xs font-medium"
:class="getStatusClass(company.basicInfo.regStatus)">
{{ company.basicInfo.regStatus }}
</span>
</div>
</div>
<!-- 底部区域风险标签和展开指示器 -->
<div class="px-4 py-2 flex items-center justify-between">
<!-- 风险标签区域 -->
<div class="flex flex-wrap gap-1">
<template v-if="getCompanyCaseTypes(company).length > 0">
<span v-for="(caseType, idx) in getCompanyCaseTypes(company).slice(0, 3)" :key="idx"
class="px-2 py-1 text-xs rounded font-medium" :class="caseType.color">
{{ caseType.text }}
</span>
<span v-if="getCompanyCaseTypes(company).length > 3"
class="px-2 py-1 text-xs rounded font-medium bg-[#EB3C3C1A] text-[#EB3C3C]">
+{{ getCompanyCaseTypes(company).length - 3 }}
</span>
</template>
<span v-else class="px-2 py-1 text-xs rounded font-medium bg-gray-50 text-gray-600">
无涉诉信息
</span>
</div>
<!-- 展开指示器 -->
<div class="absolute right-4 bottom-2 flex items-center text-xs text-gray-500">
<img src="@/assets/images/report/zk.png" alt="展开" class="w-4 h-4 container"
:class="{ 'rotate-180': isCompanyExpanded(company.orgName, 'lawsuit', index) }" />
</div>
</div>
</div>
<!-- 企业详情抽屉 - 关联企业涉诉风险 -->
<div class="mt-4 overflow-hidden transition-all duration-300 ease-in-out" :class="{
'max-h-0 opacity-0': !isCompanyExpanded(company.orgName, 'lawsuit', index),
'max-h-none opacity-100': isCompanyExpanded(company.orgName, 'lawsuit', index),
}">
<div class="mt-1 transform transition-all duration-300">
<div class="relative">
<!-- 企业基本信息 -->
<div v-if="company.basicInfo" class="mb-6 relative">
<div class="grid grid-cols-[max-content_1fr] gap-x-2 gap-y-3 p-4">
<span class="text-base text-[#666666]">企业状态</span>
<span class="text-base font-medium text-[#333333]">{{
company.basicInfo.regStatus ||
'-'
}}</span>
<span class="text-base text-[#666666]">统一社会信用代码</span>
<span class="text-base font-medium text-[#333333]">{{
company.basicInfo.creditCode
|| '-'
}}</span>
<span class="text-base text-[#666666]">注册资本</span>
<span class="text-base font-medium text-[#333333]">{{
formatCapital(company.basicInfo.regCapital,
company.basicInfo.regCapitalCurrency)
}}</span>
<span class="text-base text-[#666666]">成立日期</span>
<span class="text-base font-medium text-[#333333]">{{
formatDate(company.basicInfo.estiblishTime) }}</span>
<span class="text-base text-[#666666]">法定代表人</span>
<span class="text-base font-medium text-[#333333]">{{
company.basicInfo.legalPersonName ||
'-' }}</span>
</div>
</div>
<!-- 案件类型筛选 - 使用van-tab -->
<div v-if="getLawsuitStats(company) && getLawsuitStats(company).types.length > 0"
class="mb-6 relative">
<van-tabs :active="getCompanyActiveTab(company.orgName)" class="lawsuit-tabs"
@update:active="(name) => setCompanyActiveTab(company.orgName, name)">
<!-- 全部案件 -->
<van-tab name="all">
<template #title>
<div class="flex items-center gap-1">
<span>全部案件</span>
<span>({{ getLawsuitStats(company).total }})</span>
</div>
</template>
</van-tab>
<!-- 各类型案件 -->
<van-tab v-for="type in getLawsuitStats(company).types" :key="type.type"
:name="type.type">
<template #title>
<div class="flex items-center gap-1">
<span>{{ type.name }}</span>
<span>({{ type.count }})</span>
</div>
</template>
</van-tab>
</van-tabs>
</div>
<!-- 涉诉案件详情 -->
<template v-if="getLawsuitStats(company) && getLawsuitStats(company).types.length > 0">
<div v-for="(type, typeIndex) in getLawsuitStats(company).types" :key="typeIndex">
<div v-if="
getCompanyActiveTab(company.orgName) === 'all' ||
getCompanyActiveTab(company.orgName) === type.type
" class="mb-5 rounded-xl overflow-hidden relative">
<!-- 案件列表 -->
<div class="space-y-4 px-2">
<!-- 普通案件 -->
<div v-if="
type.type !== 'sxbzxr' &&
type.type !== 'xgbzxr'
" v-for="(
caseItem, caseIndex
) in company.lawsuitInfo.entout
.data[type.type].cases" :key="caseIndex" class="bg-white rounded-lg border border-gray-200 overflow-hidden">
<!-- 案件头部信息 - 可点击折叠 -->
<div class="cursor-pointer p-4 flex items-center justify-between"
@click="toggleCaseExpand(company.orgName, `${type.type}_${caseIndex}`)">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<!-- 案号 -->
<div class="font-medium text-gray-900 truncate">{{
caseItem.c_ah || "暂无案号"
}}</div>
<!-- 案件类型标签 -->
<span
class="px-2 py-1 text-xs rounded font-medium bg-[#EB3C3C1A] text-[#EB3C3C] flex-shrink-0">
{{ caseItem.n_ajjzjd || "状态未知" }}
</span>
</div>
<!-- 时间信息 -->
<div class="flex items-center gap-4 text-sm text-gray-500">
<div v-if="caseItem.d_larq" class="flex items-center">
<span class="mr-1">立案:</span>
<span>{{ formatDate(caseItem.d_larq) }}</span>
</div>
<div v-if="caseItem.d_jarq" class="flex items-center">
<span class="mr-1">结案:</span>
<span>{{ formatDate(caseItem.d_jarq) }}</span>
</div>
</div>
</div>
<!-- 折叠图标 -->
<img src="@/assets/images/report/zk.png" alt="展开"
class="w-4 h-4 flex-shrink-0 ml-4"
:class="{ 'rotate-180': isCaseExpanded(company.orgName, `${type.type}_${caseIndex}`) }" />
</div>
<!-- 案件详情 - 可折叠 -->
<div v-if="isCaseExpanded(company.orgName, `${type.type}_${caseIndex}`)"
class="px-4 pb-4 pt-2">
<div class="grid grid-cols-[max-content_1fr] gap-x-4 gap-y-3">
<!-- 经办法院 -->
<span class="text-base text-[#666666]">经办法院</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.n_jbfy || "-" }}</span>
<!-- 所属地域 -->
<span class="text-base text-[#666666]">所属地域</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.c_ssdy || "-" }}</span>
<!-- 案件类型 -->
<template v-if="caseItem.n_ajlx">
<span class="text-base text-[#666666]">案件类型</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.n_ajlx || "-" }}</span>
</template>
<!-- 立案时间 -->
<template v-if="caseItem.d_larq">
<span class="text-base text-[#666666]">立案时间</span>
<span class="text-base font-medium text-[#333333]">{{
formatDate(caseItem.d_larq) }}</span>
</template>
<!-- 立案案由 -->
<template v-if="caseItem.n_laay_tree">
<span class="text-base text-[#666666]">立案案由</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.n_laay_tree || caseItem.n_laay || "-"
}}</span>
</template>
<!-- 当事人信息 -->
<template
v-if="caseItem.c_dsrxx && caseItem.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 caseItem.c_dsrxx"
:key="partyIndex">
{{ party.n_ssdw || "其他" }}: {{ party.c_mc
}}<span
v-if="partyIndex < caseItem.c_dsrxx.length - 1">;
</span>
</span>
</span>
</template>
<!-- 结案方式 -->
<template
v-if="caseItem.n_ajjzjd && caseItem.n_ajjzjd.includes('已结') && caseItem.n_jafs">
<span class="text-base text-[#666666]">结案方式</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.n_jafs || "-" }}</span>
</template>
<!-- 结案时间 -->
<template
v-if="caseItem.n_ajjzjd && caseItem.n_ajjzjd.includes('已结') && caseItem.d_jarq">
<span class="text-base text-[#666666]">结案时间</span>
<span class="text-base font-medium text-[#333333]">{{
formatDate(caseItem.d_jarq) }}</span>
</template>
<!-- 结案案由 -->
<template
v-if="caseItem.n_ajjzjd && caseItem.n_ajjzjd.includes('已结') && caseItem.n_jaay_tree">
<span class="text-base text-[#666666]">结案案由</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.n_jaay_tree || "与立案案由相同" }}</span>
</template>
<!-- 相关当事人 -->
<template
v-if="caseItem.n_ajjzjd && caseItem.n_ajjzjd.includes('已结') && caseItem.c_gkws_dsr">
<span class="text-base text-[#666666]">相关当事人</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.c_gkws_dsr || "-" }}</span>
</template>
<!-- 判决结果 -->
<template
v-if="caseItem.n_ajjzjd && caseItem.n_ajjzjd.includes('已结') && caseItem.c_gkws_pjjg">
<span class="text-base text-[#666666]">判决结果</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.c_gkws_pjjg || "-" }}</span>
</template>
<!-- 后续案件信息 -->
<template v-if="caseItem.next">
<span class="text-base text-[#666666]">后续案件</span>
<span class="text-base font-medium text-[#333333]">
{{ caseItem.next.c_ah }}
<span v-if="caseItem.next.stage_type"
class="ml-2 text-xs px-2 py-0.5 rounded bg-[#EB3C3C1A] text-[#EB3C3C]">
{{
caseItem.next.stage_type === 2 ? "二审"
: caseItem.next.stage_type === 3 ? "再审"
: caseItem.next.stage_type === 4 ? "申请再审"
: caseItem.next.stage_type === 5 ? "执行"
: "其他"
}}
</span>
</span>
</template>
</div>
</div>
</div>
<!-- 失信被执行人案件 -->
<div v-if="type.type === 'sxbzxr'" v-for="(
caseItem, caseIndex
) in company.lawsuitInfo.sxbzxr
.data.sxbzxr" :key="caseIndex" class="bg-white rounded-lg border border-gray-200 overflow-hidden">
<!-- 案件头部信息 - 可点击折叠 -->
<div class="cursor-pointer p-4 flex items-center justify-between"
@click="toggleCaseExpand(company.orgName, `sxbzxr_${caseIndex}`)">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<!-- 案号 -->
<div class="font-medium text-gray-900 truncate">{{
caseItem.ah || "暂无案号"
}}</div>
<!-- 案件类型标签 -->
<span
class="px-2 py-1 text-xs rounded font-medium bg-[#EB3C3C1A] text-[#EB3C3C] flex-shrink-0">
失信被执行人
</span>
</div>
<!-- 时间信息 -->
<div class="flex items-center gap-4 text-sm text-gray-500">
<div v-if="caseItem.larq" class="flex items-center">
<span class="mr-1">立案:</span>
<span>{{ formatDate(caseItem.larq) }}</span>
</div>
<div v-if="caseItem.fbrq" class="flex items-center">
<span class="mr-1">发布:</span>
<span>{{ formatDate(caseItem.fbrq) }}</span>
</div>
</div>
</div>
<!-- 折叠图标 -->
<img src="@/assets/images/report/zk.png" alt="展开"
class="w-4 h-4 flex-shrink-0 ml-4"
:class="{ 'rotate-180': isCaseExpanded(company.orgName, `sxbzxr_${caseIndex}`) }" />
</div>
<!-- 案件详情 - 可折叠 -->
<div v-if="isCaseExpanded(company.orgName, `sxbzxr_${caseIndex}`)"
class="px-4 pb-4 pt-2">
<div class="grid grid-cols-[max-content_1fr] gap-x-4 gap-y-3">
<!-- 执行法院 -->
<span class="text-base text-[#666666]">执行法院</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.zxfy || "-" }}</span>
<!-- 所属地域 -->
<span class="text-base text-[#666666]">所属地域</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.sf || "-" }}</span>
<!-- 企业法人 -->
<template v-if="caseItem.qyfr">
<span class="text-base text-[#666666]">企业法人</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.qyfr || "-" }}</span>
</template>
<!-- 组织机构代码 -->
<template v-if="caseItem.zzjgdm">
<span class="text-base text-[#666666]">组织机构代码</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.zzjgdm || "-" }}</span>
</template>
<!-- 执行依据文号 -->
<template v-if="caseItem.zxyjwh">
<span class="text-base text-[#666666]">执行依据文号</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.zxyjwh || "-" }}</span>
</template>
<!-- 执行依据单位 -->
<template v-if="caseItem.zxyjdw">
<span class="text-base text-[#666666]">执行依据单位</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.zxyjdw || "-" }}</span>
</template>
<!-- 义务内容 -->
<template v-if="caseItem.yw">
<span class="text-base text-[#666666]">义务内容</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.yw || "-" }}</span>
</template>
<!-- 履行情况 -->
<template v-if="caseItem.lxqk">
<span class="text-base text-[#666666]">履行情况</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.lxqk || "-" }}</span>
</template>
<!-- 行为情形 -->
<template v-if="caseItem.xwqx">
<span class="text-base text-[#666666]">行为情形</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.xwqx || "-" }}</span>
</template>
<!-- 金额估计 -->
<template v-if="caseItem.pjje_gj">
<span class="text-base text-[#666666]">金额估计</span>
<span class="text-base font-medium text-[#333333]">{{
formatLawsuitMoney(caseItem.pjje_gj) || "-"
}}</span>
</template>
</div>
</div>
</div>
<!-- 限高被执行人案件 -->
<div v-if="type.type === 'xgbzxr'" v-for="(
caseItem, caseIndex
) in company.lawsuitInfo.xgbzxr
.data.xgbzxr" :key="caseIndex" class="bg-white rounded-lg border border-gray-200 overflow-hidden">
<!-- 案件头部信息 - 可点击折叠 -->
<div class="cursor-pointer p-4 flex items-center justify-between"
@click="toggleCaseExpand(company.orgName, `xgbzxr_${caseIndex}`)">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<!-- 案号 -->
<div class="font-medium text-gray-900 truncate">{{
caseItem.ah || "暂无案号"
}}</div>
<!-- 案件类型标签 -->
<span
class="px-2 py-1 text-xs rounded font-medium bg-[#EB3C3C1A] text-[#EB3C3C] flex-shrink-0">
限高被执行人
</span>
</div>
<!-- 时间信息 -->
<div class="flex items-center gap-4 text-sm text-gray-500">
<div v-if="caseItem.fbrq" class="flex items-center">
<span class="mr-1">发布:</span>
<span>{{ formatDate(caseItem.fbrq) }}</span>
</div>
</div>
</div>
<!-- 折叠图标 -->
<img src="@/assets/images/report/zk.png" alt="展开"
class="w-4 h-4 flex-shrink-0 ml-4"
:class="{ 'rotate-180': isCaseExpanded(company.orgName, `xgbzxr_${caseIndex}`) }" />
</div>
<!-- 案件详情 - 可折叠 -->
<div v-if="isCaseExpanded(company.orgName, `xgbzxr_${caseIndex}`)"
class="px-4 pb-4 pt-2">
<div class="grid grid-cols-[max-content_1fr] gap-x-4 gap-y-3">
<!-- 执行法院 -->
<span class="text-base text-[#666666]">执行法院</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.zxfy || "-" }}</span>
<!-- 标识ID -->
<template v-if="caseItem.id">
<span class="text-base text-[#666666]">标识ID</span>
<span class="text-base font-medium text-[#333333]">{{
caseItem.id || "-" }}</span>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<!-- 无案件信息时显示 -->
<template v-else>
<div class="py-8 text-center">
<div class="w-16 h-16 mx-auto mb-4 text-gray-300">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
fill="currentColor">
<path
d="M6.94 14.036c-.233.624-.43 1.2-.606 1.783.96-.697 2.101-1.139 3.418-1.304 2.513-.314 4.746-1.973 5.876-4.058l-1.456-1.455 1.413-1.415 1-1.001c.43-.43.915-1.224 1.428-2.368-5.593.867-9.018 4.292-11.074 9.818zM17 9.001L18 10c-1 3-4 6-8 6.5-2.669.334-4.336 2.167-5.002 5.5H3C4 16 6 2 21 2c-1 2.997-1.998 4.996-2.997 5.997L17 9.001z" />
</svg>
</div>
<p class="text-gray-500">
该企业暂无涉诉风险记录
</p>
</div>
</template>
</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>
<!-- 温馨提示 -->
<LRemark
content="涉诉风险展示申请人相关企业的诉讼情况,包括民事诉讼、行政诉讼、知识产权纠纷等。数据来源于各级法院的公开判决书和法官网等权威渠道。诉讼信息包括案件性质、争议金额、审理结果和诉讼地位等。高频率的诉讼或大额的争议可能暗示企业经营风险或合同纠纷。建议重点关注作为被告的案件和败诉的情况。" />
</template>
<script setup>
import LRemark from '@/components/LRemark.vue'
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { BarChart, PieChart } from "echarts/charts";
import {
GridComponent,
TooltipComponent,
TitleComponent,
LegendComponent,
} from "echarts/components";
import VChart from "vue-echarts";
import LTitle from '@/components/LTitle.vue';
import { useRiskNotifier } from '@/composables/useRiskNotifier';
// 注册必须的组件
use([
CanvasRenderer,
BarChart,
PieChart,
GridComponent,
TooltipComponent,
TitleComponent,
LegendComponent,
]);
const props = defineProps({
data: {
type: Object,
required: true,
default: () => [],
},
apiId: {
type: String,
default: '',
},
index: {
type: Number,
default: 0,
},
notifyRiskStatus: {
type: Function,
default: () => { },
},
});
const totalCompanies = computed(() => props.data.totalCompanies || 0);
const lawsuitCompanies = computed(() => props.data.lawsuitCompanies || []);
// 用于跟踪展开的企业卡片
const expandedCompanies = ref({});
// 切换展开/收起企业详情
const toggleCompanyExpand = (companyId, listType, index) => {
// 创建唯一标识符,包含企业名称、列表类型和索引
const uniqueKey = `${companyId}_${listType}_${index}`;
expandedCompanies.value[uniqueKey] = !expandedCompanies.value[uniqueKey];
};
// 检查企业是否展开
const isCompanyExpanded = (companyId, listType, index) => {
const uniqueKey = `${companyId}_${listType}_${index}`;
return !!expandedCompanies.value[uniqueKey];
};
// 计算所有关联企业的总体涉诉风险统计
const allLawsuitStats = computed(() => {
if (!lawsuitCompanies.value || lawsuitCompanies.value.length === 0)
return {
totalCompanies: 0,
highRiskCompanies: 0,
mediumRiskCompanies: 0,
lowRiskCompanies: 0,
sxbzxrCount: 0,
xgbzxrCount: 0,
totalRiskItems: 0,
normalOperatingCompanies: 0,
canceledCompanies: 0,
typeStats: {},
areaStats: {},
};
// 初始化统计数据
const stats = {
totalCompanies: lawsuitCompanies.value.length, // 有涉诉风险的企业数量
highRiskCompanies: 0,
mediumRiskCompanies: 0,
lowRiskCompanies: 0,
sxbzxrCount: 0, // 失信被执行人总数
xgbzxrCount: 0, // 限高被执行人总数
totalRiskItems: 0, // 总风险事项
normalOperatingCompanies: 0, // 正常经营企业
canceledCompanies: 0, // 吊销注销企业
typeStats: {}, // 按类型统计案件数
areaStats: {}, // 按地区统计案件数
};
// 遍历所有涉诉企业
lawsuitCompanies.value.forEach((company) => {
if (!company.lawsuitInfo) return;
// 统计企业经营状态
if (company.basicInfo && company.basicInfo.regStatus) {
if (
company.basicInfo.regStatus.includes("注销") ||
company.basicInfo.regStatus.includes("吊销")
) {
stats.canceledCompanies++;
} else if (
company.basicInfo.regStatus.includes("存续") ||
company.basicInfo.regStatus.includes("在营")
) {
stats.normalOperatingCompanies++;
}
}
// 统计风险等级
const riskLevel = getRiskLevel(company).level;
if (riskLevel === "high" || riskLevel === "medium-high") {
stats.highRiskCompanies++;
} else if (riskLevel === "medium" || riskLevel === "low-medium") {
stats.mediumRiskCompanies++;
} else {
stats.lowRiskCompanies++;
}
// 统计失信被执行人
if (
company.lawsuitInfo.sxbzxr &&
company.lawsuitInfo.sxbzxr.data &&
company.lawsuitInfo.sxbzxr.data.sxbzxr &&
company.lawsuitInfo.sxbzxr.data.sxbzxr.length > 0
) {
stats.sxbzxrCount += company.lawsuitInfo.sxbzxr.data.sxbzxr.length;
stats.totalRiskItems +=
company.lawsuitInfo.sxbzxr.data.sxbzxr.length;
stats.typeStats["sxbzxr"] =
(stats.typeStats["sxbzxr"] || 0) +
company.lawsuitInfo.sxbzxr.data.sxbzxr.length;
}
// 统计限高被执行人
if (
company.lawsuitInfo.xgbzxr &&
company.lawsuitInfo.xgbzxr.data &&
company.lawsuitInfo.xgbzxr.data.xgbzxr &&
company.lawsuitInfo.xgbzxr.data.xgbzxr.length > 0
) {
stats.xgbzxrCount += company.lawsuitInfo.xgbzxr.data.xgbzxr.length;
stats.totalRiskItems +=
company.lawsuitInfo.xgbzxr.data.xgbzxr.length;
stats.typeStats["xgbzxr"] =
(stats.typeStats["xgbzxr"] || 0) +
company.lawsuitInfo.xgbzxr.data.xgbzxr.length;
}
// 统计案件数据
if (company.lawsuitInfo.entout && company.lawsuitInfo.entout.data) {
const data = company.lawsuitInfo.entout.data;
// 按类型统计
Object.keys(lawsuitTypeMap).forEach((type) => {
if (
type !== "sxbzxr" &&
type !== "xgbzxr" &&
data[type] &&
Object.keys(data[type]).length > 0
) {
const typeData = data[type];
const count =
typeData.cases && typeData.cases.length
? typeData.cases.length
: 0;
if (count > 0) {
if (!stats.typeStats[type]) stats.typeStats[type] = 0;
stats.typeStats[type] += count;
stats.totalRiskItems += count;
}
// 统计地区分布
if (typeData.cases) {
typeData.cases.forEach((caseItem) => {
if (caseItem.c_ssdy) {
const area = caseItem.c_ssdy
.split("省")[0]
.split("市")[0]
.split("自治区")[0];
if (!stats.areaStats[area])
stats.areaStats[area] = 0;
stats.areaStats[area]++;
}
});
}
}
});
}
});
// 转换类型统计为数组格式,用于展示
stats.typeList = Object.keys(stats.typeStats)
.map((type) => ({
type,
count: stats.typeStats[type],
name: getCaseTypeText(type),
color: getCaseTypeColor(type),
darkColor: getCaseTypeDarkColor(type),
}))
.sort((a, b) => b.count - a.count);
// 转换地区统计为数组
stats.areaList = Object.keys(stats.areaStats)
.map((area) => ({
area,
count: stats.areaStats[area],
}))
.sort((a, b) => b.count - a.count);
return stats;
});
const activeTabCase = ref(null);
// 设置当前活跃的案件类型标签
const setActiveTab = (type) => {
activeTabCase.value = activeTabCase.value === type ? null : type;
};
// 检查是否是当前活跃的标签
const isActiveTab = (type) => {
return activeTabCase.value === type;
};
// 关系映射表
const lawsuitTypeMap = {
sxbzxr: {
text: "失信被执行",
color: "text-[#EB3C3C] bg-[#EB3C3C1A]",
darkColor: "bg-[#EB3C3C]",
},
xgbzxr: {
text: "限高被执行",
color: "text-[#EB3C3C] bg-[#EB3C3C1A]",
darkColor: "bg-[#EB3C3C]",
},
civil: {
text: "民事案件",
color: "text-[#EB3C3C] bg-[#EB3C3C1A]",
darkColor: "bg-[#EB3C3C]",
},
criminal: {
text: "刑事案件",
color: "text-[#EB3C3C] bg-[#EB3C3C1A]",
darkColor: "bg-[#EB3C3C]",
},
administrative: {
text: "行政案件",
color: "text-[#EB3C3C] bg-[#EB3C3C1A]",
darkColor: "bg-[#EB3C3C]",
},
preservation: {
text: "非诉保全审查",
color: "text-[#EB3C3C] bg-[#EB3C3C1A]",
darkColor: "bg-[#EB3C3C]",
},
implement: {
text: "执行案件",
color: "text-[#EB3C3C] bg-[#EB3C3C1A]",
darkColor: "bg-[#EB3C3C]",
},
bankrupt: {
text: "强制清算与破产案件",
color: "text-[#EB3C3C] bg-[#EB3C3C1A]",
darkColor: "bg-[#EB3C3C]",
},
};
// 案件类型图标
const getCaseTypeIcon = (type) => {
return "";
};
// 案件类型文本
const getCaseTypeText = (type) => {
return lawsuitTypeMap[type]?.text || "其他案件";
};
// 案件类型颜色
const getCaseTypeColor = (type) => {
return lawsuitTypeMap[type]?.color || "text-gray-600 bg-gray-50";
};
// 案件类型深色
const getCaseTypeDarkColor = (type) => {
return lawsuitTypeMap[type]?.darkColor || "bg-gray-500";
};
// 格式化资本金额显示
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 || "人民币"}`;
};
// 获取企业状态对应的样式
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-[#2B79EE1A] text-[#2B79EE]";
} else if (status.includes("筹建") || status.includes("新设")) {
return "bg-green-50 text-green-600";
} else {
return "bg-yellow-50 text-yellow-600";
}
};
// 格式化日期显示
const formatDate = (dateStr) => {
if (!dateStr) return "-";
return dateStr;
};
// 获取涉诉风险等级
const getRiskLevel = (company) => {
if (!company || !company.lawsuitInfo)
return {
level: "low",
text: "低风险",
color: "text-green-600 bg-green-50",
};
const lawsuit = company.lawsuitInfo;
// 失信被执行人是最高风险
if (
lawsuit.sxbzxr &&
lawsuit.sxbzxr.data &&
lawsuit.sxbzxr.data.sxbzxr &&
lawsuit.sxbzxr.data.sxbzxr.length > 0
) {
return {
level: "high",
text: "高风险",
color: "text-red-600 bg-red-50",
};
}
// 限高被执行人是中高风险
if (
lawsuit.xgbzxr &&
lawsuit.xgbzxr.data &&
lawsuit.xgbzxr.data.xgbzxr &&
lawsuit.xgbzxr.data.xgbzxr.length > 0
) {
return {
level: "medium-high",
text: "中高风险",
color: "text-orange-600 bg-orange-50",
};
}
// 有涉诉数据的风险级别
if (
lawsuit.entout &&
lawsuit.entout.data &&
Object.keys(lawsuit.entout.data).length > 0
) {
// 检查是否有未结案的案件
const data = lawsuit.entout.data;
if (data.count && data.count_wei_total && data.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",
};
};
// 获取涉诉案件统计
const getLawsuitStats = (company) => {
if (!company || !company.lawsuitInfo) return null;
const stats = {
total: 0,
types: [],
};
// 统计各类型案件数量
Object.keys(lawsuitTypeMap).forEach((type) => {
let count = 0;
if (type === "sxbzxr") {
count =
company.lawsuitInfo.sxbzxr &&
company.lawsuitInfo.sxbzxr.data &&
company.lawsuitInfo.sxbzxr.data.sxbzxr &&
company.lawsuitInfo.sxbzxr.data.sxbzxr.length > 0
? company.lawsuitInfo.sxbzxr.data.sxbzxr.length
: 0;
} else if (type === "xgbzxr") {
count =
company.lawsuitInfo.xgbzxr &&
company.lawsuitInfo.xgbzxr.data &&
company.lawsuitInfo.xgbzxr.data.xgbzxr &&
company.lawsuitInfo.xgbzxr.data.xgbzxr.length > 0
? company.lawsuitInfo.xgbzxr.data.xgbzxr.length
: 0;
} else if (
company.lawsuitInfo.entout &&
company.lawsuitInfo.entout.data &&
company.lawsuitInfo.entout.data[type] &&
Object.keys(company.lawsuitInfo.entout.data[type]).length > 0
) {
const typeData = company.lawsuitInfo.entout.data[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;
};
// 格式化金额显示(单位:万元)
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,
}) + " 万元"
);
};
// 获取案件状态样式
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";
}
};
// 案件类型分布图表配置
const caseTypeChartOption = computed(() => {
// 获取所有可能的案件类型,确保即使没有数据的类型也会显示
const allCaseTypes = Object.keys(lawsuitTypeMap).map((key) => ({
type: key,
name: lawsuitTypeMap[key].text,
icon: lawsuitTypeMap[key].icon,
color: lawsuitTypeMap[key].color,
darkColor: lawsuitTypeMap[key].darkColor,
count: 0, // 默认为0
}));
// 如果有统计数据,更新数量
if (
allLawsuitStats.value &&
allLawsuitStats.value.typeList &&
allLawsuitStats.value.typeList.length > 0
) {
// 用实际数据更新默认值
allLawsuitStats.value.typeList.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);
// 过滤掉数量为0的数据
const filteredData = allCaseTypes.filter((item) => item.count > 0);
const filteredCategories = filteredData.map((item) => item.name);
const filteredValues = filteredData.map((item) => item.count);
return {
tooltip: {
trigger: "axis",
formatter: function (params) {
const dataIndex = params[0].dataIndex;
return `${filteredCategories[dataIndex]}: ${filteredValues[dataIndex]}`;
},
},
grid: {
left: "5%",
right: "5%",
bottom: "5%",
top: "5%",
containLabel: true,
},
xAxis: {
type: "value",
splitLine: {
lineStyle: {
type: "dashed",
color: "#f0f0f0",
},
},
axisLabel: {
fontSize: 10,
color: "#666",
},
axisLine: {
lineStyle: {
color: "#ddd",
},
},
},
yAxis: {
type: "category",
data: filteredCategories,
axisLabel: {
fontSize: 10,
color: "#666",
},
axisLine: {
lineStyle: {
color: "#ddd",
},
},
axisTick: {
show: false,
},
},
series: [
{
name: "案件数量",
type: "bar",
barWidth: "30%",
data: filteredValues.map((value) => {
return {
value: value,
itemStyle: {
color: "#5d7eeb",
borderRadius: [0, 4, 4, 0],
},
};
}),
label: {
show: true,
position: "right",
fontSize: 10,
color: "#666",
formatter: "{c}",
},
},
],
};
});
// 在setup部分添加状态变量和计算属性
const activeCaseTypeFilter = ref("all"); // 当前选中的案件类型筛选
// 按案件类型筛选企业
const filteredLawsuitCompanies = computed(() => {
if (activeCaseTypeFilter.value === "all") {
return lawsuitCompanies.value;
}
return lawsuitCompanies.value.filter((company) => {
if (!company.lawsuitInfo) return false;
// 特殊筛选: 失信被执行人
if (activeCaseTypeFilter.value === "sxbzxr") {
return (
company.lawsuitInfo.sxbzxr &&
company.lawsuitInfo.sxbzxr.data &&
company.lawsuitInfo.sxbzxr.data.sxbzxr &&
company.lawsuitInfo.sxbzxr.data.sxbzxr.length > 0
);
}
// 特殊筛选: 限高被执行人
if (activeCaseTypeFilter.value === "xgbzxr") {
return (
company.lawsuitInfo.xgbzxr &&
company.lawsuitInfo.xgbzxr.data &&
company.lawsuitInfo.xgbzxr.data.xgbzxr &&
company.lawsuitInfo.xgbzxr.data.xgbzxr.length > 0
);
}
// 按案件类型筛选
return (
company.lawsuitInfo.entout &&
company.lawsuitInfo.entout.data &&
company.lawsuitInfo.entout.data[activeCaseTypeFilter.value] &&
company.lawsuitInfo.entout.data[activeCaseTypeFilter.value].cases &&
company.lawsuitInfo.entout.data[activeCaseTypeFilter.value].cases
.length > 0
);
});
});
// 获取每种案件类型的企业数量
const caseTypeCompanyCounts = computed(() => {
const counts = {
all: lawsuitCompanies.value.length,
};
// 初始化所有案件类型的计数
Object.keys(lawsuitTypeMap).forEach((type) => {
counts[type] = 0;
});
// 计算每种类型的企业数量
lawsuitCompanies.value.forEach((company) => {
if (!company.lawsuitInfo) return;
// 计算失信被执行人
if (
company.lawsuitInfo.sxbzxr &&
company.lawsuitInfo.sxbzxr.data &&
company.lawsuitInfo.sxbzxr.data.sxbzxr &&
company.lawsuitInfo.sxbzxr.data.sxbzxr.length > 0
) {
counts.sxbzxr++;
}
// 计算限高被执行人
if (
company.lawsuitInfo.xgbzxr &&
company.lawsuitInfo.xgbzxr.data &&
company.lawsuitInfo.xgbzxr.data.xgbzxr &&
company.lawsuitInfo.xgbzxr.data.xgbzxr.length > 0
) {
counts.xgbzxr++;
}
// 计算各类型案件
if (company.lawsuitInfo.entout && company.lawsuitInfo.entout.data) {
Object.keys(company.lawsuitInfo.entout.data).forEach((type) => {
if (
company.lawsuitInfo.entout.data[type] &&
company.lawsuitInfo.entout.data[type].cases &&
company.lawsuitInfo.entout.data[type].cases.length > 0
) {
counts[type]++;
}
});
}
});
return counts;
});
// 设置当前筛选类型
const setCaseTypeFilter = (type) => {
activeCaseTypeFilter.value = type;
};
// 获取企业涉及的案件类型
const getCompanyCaseTypes = (company) => {
if (!company || !company.lawsuitInfo) return [];
const caseTypes = [];
// 先检查特殊案件类型(按重要性降序)
// 1. 失信被执行人(最高风险)
if (
company.lawsuitInfo.sxbzxr &&
company.lawsuitInfo.sxbzxr.data &&
company.lawsuitInfo.sxbzxr.data.sxbzxr &&
company.lawsuitInfo.sxbzxr.data.sxbzxr.length > 0
) {
caseTypes.push({
type: "sxbzxr",
text: lawsuitTypeMap["sxbzxr"].text,
color: lawsuitTypeMap["sxbzxr"].color,
});
}
// 2. 限高被执行人
if (
company.lawsuitInfo.xgbzxr &&
company.lawsuitInfo.xgbzxr.data &&
company.lawsuitInfo.xgbzxr.data.xgbzxr &&
company.lawsuitInfo.xgbzxr.data.xgbzxr.length > 0
) {
caseTypes.push({
type: "xgbzxr",
text: lawsuitTypeMap["xgbzxr"].text,
color: lawsuitTypeMap["xgbzxr"].color,
});
}
// 3. 其他案件类型(按类型顺序排列)
if (company.lawsuitInfo.entout && company.lawsuitInfo.entout.data) {
// 案件类型优先级顺序
const typeOrder = [
"criminal",
"civil",
"administrative",
"implement",
"bankrupt",
"preservation",
];
// 按优先级顺序检查各类型
typeOrder.forEach((type) => {
if (
company.lawsuitInfo.entout.data[type] &&
company.lawsuitInfo.entout.data[type].cases &&
company.lawsuitInfo.entout.data[type].cases.length > 0
) {
caseTypes.push({
type,
text: lawsuitTypeMap[type].text,
color: lawsuitTypeMap[type].color,
});
}
});
}
return caseTypes;
};
// 在setup部分添加状态变量和计算属性
const companyActiveTabCase = ref({});
const caseExpandedState = ref({});
// 设置当前活跃的案件类型标签
const setCompanyActiveTab = (companyId, type) => {
companyActiveTabCase.value[companyId] = type;
};
// 检查是否是当前活跃的标签
const isCompanyActiveTab = (companyId, type) => {
return companyActiveTabCase.value[companyId] === type;
};
// 切换案件展开/折叠状态
const toggleCaseExpand = (companyId, caseIndex) => {
const key = `${companyId}_${caseIndex}`;
caseExpandedState.value[key] = !caseExpandedState.value[key];
};
// 检查案件是否展开
const isCaseExpanded = (companyId, caseIndex) => {
const key = `${companyId}_${caseIndex}`;
return caseExpandedState.value[key] || false;
};
// 获取企业当前的筛选标签,如果未设置则默认为'all'(全部)
const getCompanyActiveTab = (companyId) => {
return companyActiveTabCase.value[companyId] !== undefined
? companyActiveTabCase.value[companyId]
: 'all';
};
// 初始化企业筛选标签为全部
const initCompanyTabCase = (companyId) => {
if (companyActiveTabCase.value[companyId] === undefined) {
companyActiveTabCase.value[companyId] = 'all'; // 'all' 表示全部
}
};
// 监听企业展开状态变化,初始化筛选状态
watch(
expandedCompanies,
(newVal) => {
for (const key in newVal) {
if (newVal[key]) {
const companyId = key.split("_")[0];
initCompanyTabCase(companyId);
}
}
},
{ deep: true }
);
// 风险分布饼图配置
const riskDistributionChartOption = computed(() => {
const highRisk = allLawsuitStats.value?.highRiskCompanies || 0;
const mediumRisk = allLawsuitStats.value?.mediumRiskCompanies || 0;
const lowRisk = allLawsuitStats.value?.lowRiskCompanies || 0;
const total = highRisk + mediumRisk + lowRisk;
if (total === 0) {
return {
series: [{
type: 'pie',
radius: ['65%', '85%'],
center: ['50%', '50%'],
data: [{
value: 1,
name: '无数据',
itemStyle: {
color: '#e5e7eb',
borderRadius: 4,
borderJoinStyle: 'round'
}
}],
label: {
show: false
},
emphasis: {
disabled: true
}
}]
};
}
const data = [];
if (highRisk > 0) {
data.push({
value: highRisk,
name: '高风险',
itemStyle: {
color: '#EB3C3C',
borderRadius: 4,
borderJoinStyle: 'round'
}
});
}
if (mediumRisk > 0) {
data.push({
value: mediumRisk,
name: '中风险',
itemStyle: {
color: '#D6943E',
borderRadius: 4,
borderJoinStyle: 'round'
}
});
}
if (lowRisk > 0) {
data.push({
value: lowRisk,
name: '低风险',
itemStyle: {
color: '#1FBE5D',
borderRadius: 4,
borderJoinStyle: 'round'
}
});
}
return {
series: [{
type: 'pie',
radius: ['65%', '85%'],
center: ['50%', '50%'],
data: data,
label: {
show: false
},
emphasis: {
disabled: true
}
}]
};
});
// 初始化所有企业默认筛选状态
onMounted(() => {
if (lawsuitCompanies.value && lawsuitCompanies.value.length > 0) {
lawsuitCompanies.value.forEach((company) => {
initCompanyTabCase(company.orgName);
});
}
});
// 计算风险评分0-100分分数越高越安全
const riskScore = computed(() => {
const companies = lawsuitCompanies.value || [];
const stats = allLawsuitStats.value || {};
// 没有涉诉企业 -> 无风险 -> 100分
if (companies.length === 0) {
return 100;
}
// 有高风险企业 -> 高风险 -> 30分
if (stats.highRiskCompanies > 0) {
return 30;
}
// 有中风险企业 -> 中风险 -> 60分
if (stats.mediumRiskCompanies > 0) {
return 60;
}
// 有低风险企业 -> 低风险 -> 80分
if (stats.lowRiskCompanies > 0) {
return 80;
}
// 有企业但无风险 -> 90分
return 90;
});
// 使用 composable 通知父组件风险评分
useRiskNotifier(props, riskScore);
// 暴露给父组件
defineExpose({
riskScore
});
</script>
<style lang="scss" scoped>
.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>