2074 lines
90 KiB
HTML
2074 lines
90 KiB
HTML
|
|
<!doctype html>
|
|||
|
|
<html lang="zh-CN">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8" />
|
|||
|
|
<title>企业全景报告</title>
|
|||
|
|
<style>
|
|||
|
|
:root {
|
|||
|
|
--primary: #2563eb;
|
|||
|
|
--primary-dark: #1d4ed8;
|
|||
|
|
--text: #1f2933;
|
|||
|
|
--text-muted: #6b7280;
|
|||
|
|
--border: #e5e7eb;
|
|||
|
|
--bg-card: #fff;
|
|||
|
|
--bg-page: #f5f7fa;
|
|||
|
|
--danger: #dc2626;
|
|||
|
|
--success: #16a34a;
|
|||
|
|
--warn: #d97706;
|
|||
|
|
}
|
|||
|
|
body {
|
|||
|
|
font-family:
|
|||
|
|
-apple-system, BlinkMacSystemFont, "Segoe UI",
|
|||
|
|
"PingFang SC", "Microsoft YaHei", sans-serif;
|
|||
|
|
margin: 0;
|
|||
|
|
background: var(--bg-page);
|
|||
|
|
color: var(--text);
|
|||
|
|
line-height: 1.5;
|
|||
|
|
}
|
|||
|
|
.page {
|
|||
|
|
max-width: 1100px;
|
|||
|
|
margin: 24px auto 40px;
|
|||
|
|
padding: 16px 24px 40px;
|
|||
|
|
background: #ffffff;
|
|||
|
|
border-radius: 18px;
|
|||
|
|
border: 1px solid var(--border);
|
|||
|
|
}
|
|||
|
|
.top-nav {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
.top-nav-title {
|
|||
|
|
font-weight: 600;
|
|||
|
|
color: #111827;
|
|||
|
|
}
|
|||
|
|
.top-nav-links {
|
|||
|
|
display: flex;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
gap: 6px;
|
|||
|
|
}
|
|||
|
|
.top-nav-links a {
|
|||
|
|
padding: 0;
|
|||
|
|
border-radius: 0;
|
|||
|
|
background: transparent;
|
|||
|
|
color: var(--primary);
|
|||
|
|
text-decoration: none;
|
|||
|
|
border: none;
|
|||
|
|
cursor: default;
|
|||
|
|
pointer-events: none; /* 去掉锚点点击功能 */
|
|||
|
|
}
|
|||
|
|
.top-nav-links a:hover {
|
|||
|
|
background: transparent;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.header {
|
|||
|
|
background: linear-gradient(
|
|||
|
|
135deg,
|
|||
|
|
var(--primary),
|
|||
|
|
var(--primary-dark)
|
|||
|
|
);
|
|||
|
|
color: #fff;
|
|||
|
|
padding: 24px 28px;
|
|||
|
|
border-radius: 18px;
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: flex-start;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
gap: 16px;
|
|||
|
|
}
|
|||
|
|
.header-main {
|
|||
|
|
min-width: 0;
|
|||
|
|
}
|
|||
|
|
.header-main h1 {
|
|||
|
|
margin: 0 0 8px;
|
|||
|
|
font-size: 26px;
|
|||
|
|
word-break: break-all;
|
|||
|
|
}
|
|||
|
|
.header-main .subtitle {
|
|||
|
|
opacity: 0.9;
|
|||
|
|
font-size: 14px;
|
|||
|
|
word-break: break-all;
|
|||
|
|
}
|
|||
|
|
.header-tags {
|
|||
|
|
margin-top: 8px;
|
|||
|
|
}
|
|||
|
|
.tag {
|
|||
|
|
display: inline-block;
|
|||
|
|
padding: 4px 10px;
|
|||
|
|
border-radius: 999px;
|
|||
|
|
font-size: 12px;
|
|||
|
|
margin-right: 6px;
|
|||
|
|
margin-bottom: 4px;
|
|||
|
|
background: rgba(255, 255, 255, 0.2);
|
|||
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|||
|
|
}
|
|||
|
|
.header-score {
|
|||
|
|
text-align: right;
|
|||
|
|
min-width: 140px;
|
|||
|
|
}
|
|||
|
|
.header-score .score {
|
|||
|
|
font-size: 32px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
.header-score .label {
|
|||
|
|
font-size: 13px;
|
|||
|
|
opacity: 0.85;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.report-sections {
|
|||
|
|
margin-top: 24px;
|
|||
|
|
}
|
|||
|
|
.section-card {
|
|||
|
|
background: transparent;
|
|||
|
|
border-radius: 0;
|
|||
|
|
padding: 18px 0 22px;
|
|||
|
|
/* 去掉阴影,保持简洁报告风格 */
|
|||
|
|
box-shadow: none !important;
|
|||
|
|
border: none;
|
|||
|
|
border-bottom: 1px solid var(--border);
|
|||
|
|
scroll-margin-top: 16px;
|
|||
|
|
}
|
|||
|
|
.section-card:last-of-type {
|
|||
|
|
border-bottom: none;
|
|||
|
|
}
|
|||
|
|
.section-card + .section-card {
|
|||
|
|
margin-top: 12px; /* 大模块上下留间距 */
|
|||
|
|
}
|
|||
|
|
.section-card h2 {
|
|||
|
|
margin: 0 0 16px;
|
|||
|
|
font-size: 17px;
|
|||
|
|
border-left: 4px solid var(--primary);
|
|||
|
|
padding-left: 10px;
|
|||
|
|
color: #111827;
|
|||
|
|
}
|
|||
|
|
.section-card h3 {
|
|||
|
|
margin: 16px 0 8px;
|
|||
|
|
font-size: 14px;
|
|||
|
|
color: #374151;
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
.section-card h3:first-of-type {
|
|||
|
|
margin-top: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 保持单列布局,模块上下排列,便于阅读和导出 */
|
|||
|
|
|
|||
|
|
.kv-table {
|
|||
|
|
width: 100%;
|
|||
|
|
border-collapse: collapse;
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
.kv-table th,
|
|||
|
|
.kv-table td {
|
|||
|
|
padding: 8px 10px;
|
|||
|
|
vertical-align: top;
|
|||
|
|
border-bottom: 1px solid #f3f4f6;
|
|||
|
|
}
|
|||
|
|
.kv-table th {
|
|||
|
|
width: 140px;
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
font-weight: 500;
|
|||
|
|
text-align: left;
|
|||
|
|
}
|
|||
|
|
.kv-table td {
|
|||
|
|
word-break: break-word;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 主体概览:多列网格,节省纵向空间 */
|
|||
|
|
.kv-grid {
|
|||
|
|
--cols: 3;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(var(--cols), 1fr);
|
|||
|
|
gap: 10px 24px;
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
.kv-grid {
|
|||
|
|
--cols: 2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.kv-grid .kv-pair {
|
|||
|
|
display: flex;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
gap: 4px 6px;
|
|||
|
|
padding: 6px 0;
|
|||
|
|
border-bottom: 1px solid #f3f4f6;
|
|||
|
|
align-items: baseline;
|
|||
|
|
}
|
|||
|
|
.kv-grid .kv-pair .k {
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
font-weight: 500;
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
}
|
|||
|
|
.kv-grid .kv-pair .k::after {
|
|||
|
|
content: ":";
|
|||
|
|
}
|
|||
|
|
.kv-grid .kv-pair .v {
|
|||
|
|
word-break: break-word;
|
|||
|
|
min-width: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.item-list {
|
|||
|
|
list-style: none;
|
|||
|
|
padding: 0;
|
|||
|
|
margin: 0;
|
|||
|
|
}
|
|||
|
|
.item-list li {
|
|||
|
|
padding: 10px 12px;
|
|||
|
|
border-bottom: 1px dashed var(--border);
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
.item-list li:last-child {
|
|||
|
|
border-bottom: none;
|
|||
|
|
}
|
|||
|
|
.item-list li .item-title {
|
|||
|
|
font-weight: 600;
|
|||
|
|
margin-bottom: 4px;
|
|||
|
|
}
|
|||
|
|
.item-list li .item-meta {
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
.item-block {
|
|||
|
|
background: #f9fafb;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
padding: 10px 12px;
|
|||
|
|
margin-bottom: 8px;
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
.item-block .item-kv {
|
|||
|
|
margin: 4px 0;
|
|||
|
|
}
|
|||
|
|
.item-block .item-kv span.k {
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
margin-right: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.empty-hint {
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
font-size: 13px;
|
|||
|
|
padding: 12px 0;
|
|||
|
|
}
|
|||
|
|
.count-hint {
|
|||
|
|
font-size: 12px;
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
margin-bottom: 8px;
|
|||
|
|
}
|
|||
|
|
.pill {
|
|||
|
|
display: inline-flex;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 2px 8px;
|
|||
|
|
border-radius: 999px;
|
|||
|
|
font-size: 11px;
|
|||
|
|
margin-left: 6px;
|
|||
|
|
}
|
|||
|
|
.pill.low {
|
|||
|
|
background: #ecfdf3;
|
|||
|
|
color: #166534;
|
|||
|
|
}
|
|||
|
|
.pill.mid {
|
|||
|
|
background: #fef9c3;
|
|||
|
|
color: #92400e;
|
|||
|
|
}
|
|||
|
|
.pill.high {
|
|||
|
|
background: #fee2e2;
|
|||
|
|
color: #b91c1c;
|
|||
|
|
}
|
|||
|
|
.risk-row {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
padding: 4px 0;
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
.risk-row .ok {
|
|||
|
|
color: var(--success);
|
|||
|
|
}
|
|||
|
|
.risk-row .bad {
|
|||
|
|
color: var(--danger);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 风险点一览:多列彩色标签 */
|
|||
|
|
.risk-points-grid {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|||
|
|
gap: 6px 12px;
|
|||
|
|
margin-top: 4px;
|
|||
|
|
}
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
.risk-points-grid {
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.risk-point {
|
|||
|
|
font-size: 13px;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 6px;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
}
|
|||
|
|
.risk-point-name {
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
}
|
|||
|
|
.risk-status-ok {
|
|||
|
|
color: var(--success);
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
.risk-status-bad {
|
|||
|
|
color: var(--danger);
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.raw-section summary {
|
|||
|
|
cursor: pointer;
|
|||
|
|
padding: 8px 0;
|
|||
|
|
font-weight: 600;
|
|||
|
|
color: var(--text-muted);
|
|||
|
|
}
|
|||
|
|
.raw-section pre {
|
|||
|
|
font-size: 11px;
|
|||
|
|
background: #0f172a;
|
|||
|
|
color: #e2e8f0;
|
|||
|
|
padding: 12px;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
overflow: auto;
|
|||
|
|
max-height: 320px;
|
|||
|
|
}
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
.header {
|
|||
|
|
flex-direction: column;
|
|||
|
|
}
|
|||
|
|
.header-score {
|
|||
|
|
text-align: left;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/* 打印 / 导出 PDF 友好布局 */
|
|||
|
|
@media print {
|
|||
|
|
body {
|
|||
|
|
background: #ffffff !important;
|
|||
|
|
margin: 0;
|
|||
|
|
-webkit-print-color-adjust: exact;
|
|||
|
|
print-color-adjust: exact;
|
|||
|
|
}
|
|||
|
|
.page {
|
|||
|
|
max-width: none;
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 10mm 12mm 12mm;
|
|||
|
|
}
|
|||
|
|
/* 导出 PDF 时隐藏导航 */
|
|||
|
|
.top-nav {
|
|||
|
|
display: none !important;
|
|||
|
|
}
|
|||
|
|
/* 抬头简化为白底、去圆角和阴影 */
|
|||
|
|
.header {
|
|||
|
|
background: #ffffff !important;
|
|||
|
|
color: #111827 !important;
|
|||
|
|
border-radius: 0;
|
|||
|
|
box-shadow: none;
|
|||
|
|
padding: 10px 0 8px;
|
|||
|
|
border-bottom: 1px solid #e5e7eb;
|
|||
|
|
}
|
|||
|
|
.header-score .score {
|
|||
|
|
font-size: 26px;
|
|||
|
|
}
|
|||
|
|
/* 主体卡片:去阴影,避免被分页截断 */
|
|||
|
|
.section-card {
|
|||
|
|
box-shadow: none;
|
|||
|
|
border-radius: 0;
|
|||
|
|
page-break-inside: avoid;
|
|||
|
|
break-inside: avoid;
|
|||
|
|
}
|
|||
|
|
.section-card h2 {
|
|||
|
|
page-break-after: avoid;
|
|||
|
|
}
|
|||
|
|
.item-list li {
|
|||
|
|
page-break-inside: avoid;
|
|||
|
|
break-inside: avoid;
|
|||
|
|
}
|
|||
|
|
/* 原始 JSON 展示在 PDF 中通常不需要过高容器限制 */
|
|||
|
|
.raw-section pre {
|
|||
|
|
max-height: none;
|
|||
|
|
page-break-inside: avoid;
|
|||
|
|
break-inside: avoid;
|
|||
|
|
}
|
|||
|
|
a {
|
|||
|
|
color: #111827;
|
|||
|
|
text-decoration: none;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="page">
|
|||
|
|
<!-- 隐藏的导航容器,仅用于脚本生成目录,页面不展示 -->
|
|||
|
|
<nav class="top-nav">
|
|||
|
|
<div id="navLinks"></div>
|
|||
|
|
</nav>
|
|||
|
|
<header class="header">
|
|||
|
|
<div class="header-main">
|
|||
|
|
<h1 class="report-title">企业全景报告</h1>
|
|||
|
|
<div class="subtitle">
|
|||
|
|
<span id="entName">企业名称</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="subtitle">
|
|||
|
|
<span id="creditCodeLabel">统一社会信用代码:-</span> ·
|
|||
|
|
<span id="entStatusLabel">经营状态:-</span> ·
|
|||
|
|
<span id="entTypeLabel">企业类型:-</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="header-tags" id="headerTags"></div>
|
|||
|
|
<div
|
|||
|
|
style="opacity: 0.9; font-size: 12px; margin-top: 6px"
|
|||
|
|
id="reportTimeLabel"
|
|||
|
|
>
|
|||
|
|
报告生成时间:-
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="header-score">
|
|||
|
|
<div class="score" id="overallScore">--</div>
|
|||
|
|
<div class="label">
|
|||
|
|
综合评分
|
|||
|
|
<span id="riskLevelPill" class="pill low">风险:-</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</header>
|
|||
|
|
<main id="reportSections" class="report-sections"></main>
|
|||
|
|
</div>
|
|||
|
|
<script>
|
|||
|
|
(function () {
|
|||
|
|
// 后端通过模板引擎注入的企业报告数据(QYGLJ1U9 聚合结果)
|
|||
|
|
// ReportJSON 为合法的 JSON 对象字面量
|
|||
|
|
var reportData = {{ .ReportJSON }};
|
|||
|
|
var sectionOrder = [
|
|||
|
|
"riskOverview",
|
|||
|
|
"basic",
|
|||
|
|
"branches",
|
|||
|
|
"shareholding",
|
|||
|
|
"controller",
|
|||
|
|
"beneficiaries",
|
|||
|
|
"investments",
|
|||
|
|
"guarantees",
|
|||
|
|
"management",
|
|||
|
|
"assets",
|
|||
|
|
"licenses",
|
|||
|
|
"activities",
|
|||
|
|
"inspections",
|
|||
|
|
"risks",
|
|||
|
|
"timeline",
|
|||
|
|
"listed",
|
|||
|
|
];
|
|||
|
|
var sectionTitles = {
|
|||
|
|
riskOverview: "风险情况(综合分析)",
|
|||
|
|
basic: "一、主体概览(企业基础信息)",
|
|||
|
|
branches: "二、分支机构",
|
|||
|
|
shareholding: "三、股权与控制",
|
|||
|
|
controller: "四、实际控制人",
|
|||
|
|
beneficiaries: "五、最终受益人",
|
|||
|
|
investments: "六、对外投资",
|
|||
|
|
guarantees: "七、对外担保",
|
|||
|
|
management: "八、人员与组织",
|
|||
|
|
assets: "九、资产与经营(年报)",
|
|||
|
|
licenses: "十、行政许可与资质",
|
|||
|
|
activities: "十一、经营活动",
|
|||
|
|
inspections: "十二、抽查检查",
|
|||
|
|
risks: "十三、风险与合规",
|
|||
|
|
timeline: "十四、发展时间线",
|
|||
|
|
listed: "十五、上市信息",
|
|||
|
|
};
|
|||
|
|
// 保持所有板块单列纵向排布
|
|||
|
|
var keyLabels = {
|
|||
|
|
entName: "企业名称",
|
|||
|
|
creditCode: "统一社会信用代码",
|
|||
|
|
regNo: "注册号",
|
|||
|
|
orgCode: "组织机构代码",
|
|||
|
|
entType: "企业类型",
|
|||
|
|
entTypeCode: "企业类型编码",
|
|||
|
|
entityTypeCode: "实体类型编码",
|
|||
|
|
establishDate: "成立日期",
|
|||
|
|
registeredCapital: "注册资本",
|
|||
|
|
regCap: "注册资本",
|
|||
|
|
regCapCurrency: "注册资本币种",
|
|||
|
|
regCapCurrencyCode: "注册资本币种代码",
|
|||
|
|
regOrg: "登记机关",
|
|||
|
|
regOrgCode: "注册地址行政编号",
|
|||
|
|
regProvince: "所在省份",
|
|||
|
|
provinceCode: "所在省份编码",
|
|||
|
|
regCity: "所在城市",
|
|||
|
|
regCityCode: "所在城市编码",
|
|||
|
|
regDistrict: "所在区/县",
|
|||
|
|
districtCode: "所在区/县编码",
|
|||
|
|
address: "住址",
|
|||
|
|
postalCode: "邮编",
|
|||
|
|
legalRepresentative: "法定代表人",
|
|||
|
|
compositionForm: "组成形式",
|
|||
|
|
approvedBusinessItem: "许可经营项目",
|
|||
|
|
status: "经营状态",
|
|||
|
|
statusCode: "经营状态编码",
|
|||
|
|
operationPeriodFrom: "经营期限自",
|
|||
|
|
operationPeriodTo: "经营期限至",
|
|||
|
|
approveDate: "核准日期",
|
|||
|
|
cancelDate: "注销日期",
|
|||
|
|
revokeDate: "吊销日期",
|
|||
|
|
cancelReason: "注销原因",
|
|||
|
|
revokeReason: "吊销原因",
|
|||
|
|
oldNames: "曾用名",
|
|||
|
|
businessScope: "经营业务范围",
|
|||
|
|
lastAnnuReportYear: "最后年检年度",
|
|||
|
|
name: "名称",
|
|||
|
|
type: "类型",
|
|||
|
|
percent: "比例",
|
|||
|
|
reason: "判定依据",
|
|||
|
|
source: "来源",
|
|||
|
|
id: "标识",
|
|||
|
|
path: "控制路径",
|
|||
|
|
topHolderName: "第一大股东",
|
|||
|
|
topHolderPercent: "第一大股东持股",
|
|||
|
|
top5TotalPercent: "前五大合计",
|
|||
|
|
shareholderCount: "股东总数",
|
|||
|
|
currency: "币种",
|
|||
|
|
hasEquityPledges: "存在股权出质",
|
|||
|
|
riskLevel: "风险等级",
|
|||
|
|
riskScore: "风险得分",
|
|||
|
|
totalCount: "对外投资数量",
|
|||
|
|
totalAmount: "投资总额(万)",
|
|||
|
|
employeeCount: "从业人数",
|
|||
|
|
femaleEmployeeCount: "女性从业人数",
|
|||
|
|
yearReportId: "年报标识",
|
|||
|
|
investor: "股东/投资人",
|
|||
|
|
changeDate: "变更日期",
|
|||
|
|
detailBefore: "变更前",
|
|||
|
|
detailAfter: "变更后",
|
|||
|
|
changeType: "变更类型",
|
|||
|
|
updateDate: "变更日期",
|
|||
|
|
updateContent: "变更内容",
|
|||
|
|
date: "日期",
|
|||
|
|
title: "标题",
|
|||
|
|
overallScore: "总体评分",
|
|||
|
|
tags: "标签",
|
|||
|
|
isListed: "是否上市",
|
|||
|
|
company: "上市公司信息",
|
|||
|
|
stock: "股票信息",
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function label(key) {
|
|||
|
|
return keyLabels[key] || key;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function esc(s) {
|
|||
|
|
if (s == null || s === "") return "-";
|
|||
|
|
return String(s);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 职务字段格式化:部分数据源为英文/代码,如 EXEC、EXEC&&LR、HEXEC
|
|||
|
|
function formatPosition(position) {
|
|||
|
|
if (!position) return "";
|
|||
|
|
var p = String(position).trim();
|
|||
|
|
if (!p) return "";
|
|||
|
|
// 将可能存在的转义形式统一为普通字符
|
|||
|
|
p = p.replace(/\\u0026/gi, "&");
|
|||
|
|
// 已知常见职务代码映射
|
|||
|
|
var dict = {
|
|||
|
|
EXEC: "高管",
|
|||
|
|
LR: "法定代表人",
|
|||
|
|
HEXEC: "执行合伙人",
|
|||
|
|
};
|
|||
|
|
// 拆分出可能的代码片段(用非字母字符作为分隔)
|
|||
|
|
var parts = p
|
|||
|
|
.split(/[^A-Z]/i)
|
|||
|
|
.map(function (s) {
|
|||
|
|
return s.trim();
|
|||
|
|
})
|
|||
|
|
.filter(Boolean);
|
|||
|
|
if (parts.length === 0) {
|
|||
|
|
return p;
|
|||
|
|
}
|
|||
|
|
var mapped = parts.map(function (code) {
|
|||
|
|
return dict[code] || code;
|
|||
|
|
});
|
|||
|
|
// 多个角色用顿号连接,例如 "高管、法定代表人"
|
|||
|
|
return mapped.join("、");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderCell(v) {
|
|||
|
|
if (v == null || v === "") return "-";
|
|||
|
|
if (typeof v === "boolean") return v ? "是" : "否";
|
|||
|
|
if (typeof v === "number") return v;
|
|||
|
|
if (typeof v === "object") {
|
|||
|
|
if (Array.isArray(v))
|
|||
|
|
return v.length ? "共 " + v.length + " 条" : "-";
|
|||
|
|
return "对象";
|
|||
|
|
}
|
|||
|
|
return esc(v);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 传入 keys 时:渲染所有键,无值显示 -;未传 keys 时:按对象自身键渲染
|
|||
|
|
function kvTable(obj, keys) {
|
|||
|
|
if (!obj || typeof obj !== "object")
|
|||
|
|
return "<p class='empty-hint'>暂无数据</p>";
|
|||
|
|
var keyList = keys && keys.length ? keys : Object.keys(obj);
|
|||
|
|
var rows = keyList.map(function (k) {
|
|||
|
|
return (
|
|||
|
|
"<tr><th>" +
|
|||
|
|
esc(label(k)) +
|
|||
|
|
"</th><td>" +
|
|||
|
|
renderCell(obj[k]) +
|
|||
|
|
"</td></tr>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
return rows.length
|
|||
|
|
? "<table class='kv-table'>" +
|
|||
|
|
rows.join("") +
|
|||
|
|
"</table>"
|
|||
|
|
: "<p class='empty-hint'>暂无数据</p>";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 多列网格展示 key-value,用于主体概览等需节省纵向空间的区块
|
|||
|
|
function kvGrid(obj, keys, cols) {
|
|||
|
|
if (!obj || typeof obj !== "object")
|
|||
|
|
return "<p class='empty-hint'>暂无数据</p>";
|
|||
|
|
var keyList = keys && keys.length ? keys : Object.keys(obj);
|
|||
|
|
var parts = keyList.map(function (k) {
|
|||
|
|
return (
|
|||
|
|
"<div class='kv-pair'><span class='k'>" +
|
|||
|
|
esc(label(k)) +
|
|||
|
|
"</span><span class='v'>" +
|
|||
|
|
renderCell(obj[k]) +
|
|||
|
|
"</span></div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
var c = cols || 3;
|
|||
|
|
return parts.length
|
|||
|
|
? "<div class='kv-grid' style='--cols:" +
|
|||
|
|
c +
|
|||
|
|
"'>" +
|
|||
|
|
parts.join("") +
|
|||
|
|
"</div>"
|
|||
|
|
: "<p class='empty-hint'>暂无数据</p>";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function itemList(arr, fn) {
|
|||
|
|
if (!Array.isArray(arr) || !arr.length)
|
|||
|
|
return "<p class='empty-hint'>暂无数据</p>";
|
|||
|
|
var html =
|
|||
|
|
"<p class='count-hint'>共 " +
|
|||
|
|
arr.length +
|
|||
|
|
" 条</p><ul class='item-list'>";
|
|||
|
|
arr.forEach(function (item, i) {
|
|||
|
|
html +=
|
|||
|
|
"<li>" +
|
|||
|
|
(fn
|
|||
|
|
? fn(item, i)
|
|||
|
|
: typeof item === "object"
|
|||
|
|
? JSON.stringify(item)
|
|||
|
|
: esc(item)) +
|
|||
|
|
"</li>";
|
|||
|
|
});
|
|||
|
|
return html + "</ul>";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderBasic(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无基础信息</p>";
|
|||
|
|
// 与《企业全量信息核验V2_返回字段说明》BASIC 字段顺序对应
|
|||
|
|
var keys = [
|
|||
|
|
"entName",
|
|||
|
|
"creditCode",
|
|||
|
|
"regNo",
|
|||
|
|
"orgCode",
|
|||
|
|
"entType",
|
|||
|
|
"entTypeCode",
|
|||
|
|
"entityTypeCode",
|
|||
|
|
"establishDate",
|
|||
|
|
"registeredCapital",
|
|||
|
|
"regCap",
|
|||
|
|
"regCapCurrency",
|
|||
|
|
"regCapCurrencyCode",
|
|||
|
|
"regOrg",
|
|||
|
|
"regOrgCode",
|
|||
|
|
"regProvince",
|
|||
|
|
"provinceCode",
|
|||
|
|
"regCity",
|
|||
|
|
"regCityCode",
|
|||
|
|
"regDistrict",
|
|||
|
|
"districtCode",
|
|||
|
|
"address",
|
|||
|
|
"postalCode",
|
|||
|
|
"legalRepresentative",
|
|||
|
|
"compositionForm",
|
|||
|
|
"approvedBusinessItem",
|
|||
|
|
"status",
|
|||
|
|
"statusCode",
|
|||
|
|
"operationPeriodFrom",
|
|||
|
|
"operationPeriodTo",
|
|||
|
|
"approveDate",
|
|||
|
|
"cancelDate",
|
|||
|
|
"revokeDate",
|
|||
|
|
"cancelReason",
|
|||
|
|
"revokeReason",
|
|||
|
|
"oldNames",
|
|||
|
|
"businessScope",
|
|||
|
|
"lastAnnuReportYear",
|
|||
|
|
];
|
|||
|
|
var o = {};
|
|||
|
|
for (var k in v) o[k] = v[k];
|
|||
|
|
// 曾用名:统一为字符串展示,无数据时显示 -(保证「曾用名」行始终出现)
|
|||
|
|
o.oldNames =
|
|||
|
|
v.oldNames &&
|
|||
|
|
Array.isArray(v.oldNames) &&
|
|||
|
|
v.oldNames.length
|
|||
|
|
? v.oldNames.join(";")
|
|||
|
|
: v.oldNames || "-";
|
|||
|
|
return kvGrid(o, keys, 3);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderBranches(v) {
|
|||
|
|
return itemList(v, function (b) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(b.name) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>注册号:" +
|
|||
|
|
esc(b.regNo) +
|
|||
|
|
";信用代码:" +
|
|||
|
|
esc(b.creditCode) +
|
|||
|
|
";登记机关:" +
|
|||
|
|
esc(b.regOrg) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderShareholding(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无股权信息</p>";
|
|||
|
|
var html = "";
|
|||
|
|
var summaryKeys = [
|
|||
|
|
"shareholderCount",
|
|||
|
|
"registeredCapital",
|
|||
|
|
"currency",
|
|||
|
|
"topHolderName",
|
|||
|
|
"topHolderPercent",
|
|||
|
|
"top5TotalPercent",
|
|||
|
|
"hasEquityPledges",
|
|||
|
|
];
|
|||
|
|
var hasAny = summaryKeys.some(function (k) {
|
|||
|
|
return (
|
|||
|
|
v[k] !== undefined && v[k] !== null && v[k] !== ""
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
if (hasAny) {
|
|||
|
|
var rows = [];
|
|||
|
|
// 股东总数
|
|||
|
|
if (v.shareholderCount != null) {
|
|||
|
|
rows.push({
|
|||
|
|
k: "股东总数",
|
|||
|
|
v: esc(v.shareholderCount),
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
// 注册资本(加单位元)
|
|||
|
|
if (v.registeredCapital != null) {
|
|||
|
|
rows.push({
|
|||
|
|
k: "注册资本",
|
|||
|
|
v: esc(v.registeredCapital) + " 元",
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
// 币种
|
|||
|
|
if (v.currency) {
|
|||
|
|
rows.push({
|
|||
|
|
k: "币种",
|
|||
|
|
v: esc(v.currency),
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
// 第一大股东及持股
|
|||
|
|
if (v.topHolderName || v.topHolderPercent != null) {
|
|||
|
|
rows.push({
|
|||
|
|
k: "第一大股东",
|
|||
|
|
v: esc(v.topHolderName || "-"),
|
|||
|
|
});
|
|||
|
|
if (v.topHolderPercent != null) {
|
|||
|
|
rows.push({
|
|||
|
|
k: "第一大股东持股",
|
|||
|
|
v:
|
|||
|
|
(v.topHolderPercent * 100).toFixed(1) +
|
|||
|
|
"%",
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 前五大合计
|
|||
|
|
if (v.top5TotalPercent != null) {
|
|||
|
|
rows.push({
|
|||
|
|
k: "前五大合计",
|
|||
|
|
v: (v.top5TotalPercent * 100).toFixed(1) + "%",
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
// 是否存在股权出质
|
|||
|
|
if (v.hasEquityPledges != null) {
|
|||
|
|
rows.push({
|
|||
|
|
k: "存在股权出质",
|
|||
|
|
v: v.hasEquityPledges ? "是" : "否",
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
if (rows.length) {
|
|||
|
|
var t =
|
|||
|
|
"<table class='kv-table'><tbody>" +
|
|||
|
|
rows
|
|||
|
|
.map(function (r) {
|
|||
|
|
return (
|
|||
|
|
"<tr><th>" +
|
|||
|
|
esc(r.k) +
|
|||
|
|
"</th><td>" +
|
|||
|
|
esc(r.v) +
|
|||
|
|
"</td></tr>"
|
|||
|
|
);
|
|||
|
|
})
|
|||
|
|
.join("") +
|
|||
|
|
"</tbody></table>";
|
|||
|
|
html += "<h3>股权汇总</h3>" + t;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 股东明细:优先展示来自股权全景/全量信息的有效字段,避免大段空白
|
|||
|
|
html +=
|
|||
|
|
"<h3>股东明细</h3>" +
|
|||
|
|
itemList(v.shareholders, function (sh) {
|
|||
|
|
var pct =
|
|||
|
|
(sh.ownershipPercent != null
|
|||
|
|
? sh.ownershipPercent
|
|||
|
|
: sh.sharePercent) || 0;
|
|||
|
|
var title =
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(sh.name) +
|
|||
|
|
"(" +
|
|||
|
|
(pct * 100).toFixed(1) +
|
|||
|
|
"%)</div>";
|
|||
|
|
var parts = [];
|
|||
|
|
if (sh.type) {
|
|||
|
|
parts.push("类型:" + esc(sh.type));
|
|||
|
|
}
|
|||
|
|
if (
|
|||
|
|
sh.subscribedAmount != null &&
|
|||
|
|
sh.subscribedAmount !== ""
|
|||
|
|
) {
|
|||
|
|
var sub = "认缴:" + esc(sh.subscribedAmount);
|
|||
|
|
if (
|
|||
|
|
sh.subscribedCurrency ||
|
|||
|
|
sh.subscribedCurrencyCode
|
|||
|
|
) {
|
|||
|
|
sub +=
|
|||
|
|
" " +
|
|||
|
|
esc(sh.subscribedCurrency || "") +
|
|||
|
|
(sh.subscribedCurrencyCode
|
|||
|
|
? "(" +
|
|||
|
|
esc(sh.subscribedCurrencyCode) +
|
|||
|
|
")"
|
|||
|
|
: "");
|
|||
|
|
}
|
|||
|
|
parts.push(sub);
|
|||
|
|
}
|
|||
|
|
if (sh.subscribedDate) {
|
|||
|
|
parts.push("认缴日:" + esc(sh.subscribedDate));
|
|||
|
|
}
|
|||
|
|
if (
|
|||
|
|
sh.subscribedMethod ||
|
|||
|
|
sh.subscribedMethodCode
|
|||
|
|
) {
|
|||
|
|
var subm =
|
|||
|
|
"认缴方式:" +
|
|||
|
|
esc(sh.subscribedMethod || "");
|
|||
|
|
if (sh.subscribedMethodCode) {
|
|||
|
|
subm +=
|
|||
|
|
"(" +
|
|||
|
|
esc(sh.subscribedMethodCode) +
|
|||
|
|
")";
|
|||
|
|
}
|
|||
|
|
parts.push(subm);
|
|||
|
|
}
|
|||
|
|
if (sh.paidAmount != null && sh.paidAmount !== "") {
|
|||
|
|
parts.push("实缴:" + esc(sh.paidAmount));
|
|||
|
|
}
|
|||
|
|
if (sh.paidDate) {
|
|||
|
|
parts.push("实缴日:" + esc(sh.paidDate));
|
|||
|
|
}
|
|||
|
|
if (sh.paidMethod) {
|
|||
|
|
parts.push("实缴方式:" + esc(sh.paidMethod));
|
|||
|
|
}
|
|||
|
|
if (sh.creditCode) {
|
|||
|
|
parts.push(
|
|||
|
|
"股东信用代码:" + esc(sh.creditCode),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
if (sh.regNo) {
|
|||
|
|
parts.push("股东注册号:" + esc(sh.regNo));
|
|||
|
|
}
|
|||
|
|
if (sh.isHistory != null) {
|
|||
|
|
parts.push(
|
|||
|
|
"是否历史:" + (sh.isHistory ? "是" : "否"),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
var meta =
|
|||
|
|
parts.length > 0
|
|||
|
|
? "<div class='item-meta'>" +
|
|||
|
|
parts.join(";") +
|
|||
|
|
"</div>"
|
|||
|
|
: "";
|
|||
|
|
return title + meta;
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>股权变更记录</h3>" +
|
|||
|
|
itemList(v.equityChanges, function (e) {
|
|||
|
|
var name = e.shareholderName;
|
|||
|
|
// 如果是纯数字(可能是内部ID),在标题中不展示
|
|||
|
|
var isId =
|
|||
|
|
typeof name === "string" &&
|
|||
|
|
/^[0-9]+$/.test(name);
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(e.changeDate) +
|
|||
|
|
(isId || !name
|
|||
|
|
? ""
|
|||
|
|
: " " + esc(e.shareholderName)) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>变更前:" +
|
|||
|
|
esc(e.percentBefore) +
|
|||
|
|
" → 变更后:" +
|
|||
|
|
esc(e.percentAfter) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>股权出质</h3>" +
|
|||
|
|
itemList(v.equityPledges, function (e) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(e.regNo) +
|
|||
|
|
" " +
|
|||
|
|
esc(e.pledgor) +
|
|||
|
|
" → " +
|
|||
|
|
esc(e.pledgee) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>出质数额:" +
|
|||
|
|
esc(e.pledgedAmount) +
|
|||
|
|
" 元" +
|
|||
|
|
";登记日:" +
|
|||
|
|
esc(e.regDate) +
|
|||
|
|
";状态:" +
|
|||
|
|
esc(e.status) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>实缴出资明细</h3>" +
|
|||
|
|
itemList(v.paidInDetails, function (e) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(e.investor) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>日期:" +
|
|||
|
|
esc(e.paidDate) +
|
|||
|
|
";方式:" +
|
|||
|
|
esc(e.paidMethod) +
|
|||
|
|
";累计实缴:" +
|
|||
|
|
esc(e.accumulatedPaid) +
|
|||
|
|
" 万元" +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>认缴出资明细</h3>" +
|
|||
|
|
itemList(v.subscribedCapitalDetails, function (e) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(e.investor) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>认缴日:" +
|
|||
|
|
esc(e.subscribedDate) +
|
|||
|
|
";方式:" +
|
|||
|
|
esc(e.subscribedMethod) +
|
|||
|
|
";累计认缴:" +
|
|||
|
|
esc(e.accumulatedSubscribed) +
|
|||
|
|
" 元" +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderController(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无实控人信息</p>";
|
|||
|
|
var html = kvTable(v, [
|
|||
|
|
"id",
|
|||
|
|
"name",
|
|||
|
|
"type",
|
|||
|
|
"percent",
|
|||
|
|
"reason",
|
|||
|
|
"source",
|
|||
|
|
]);
|
|||
|
|
if (v.path && typeof v.path === "object") {
|
|||
|
|
html += "<h3>控制路径</h3>";
|
|||
|
|
if (v.path.nodes && v.path.nodes.length) {
|
|||
|
|
html +=
|
|||
|
|
"<p class='count-hint'>节点 " +
|
|||
|
|
v.path.nodes.length +
|
|||
|
|
" 个</p>";
|
|||
|
|
v.path.nodes.forEach(function (n) {
|
|||
|
|
var id =
|
|||
|
|
n.entityId != null ? n.entityId : n.uid;
|
|||
|
|
html +=
|
|||
|
|
"<div class='item-block'><span class='k'>" +
|
|||
|
|
esc(n.label) +
|
|||
|
|
"</span>" +
|
|||
|
|
esc(n.name) +
|
|||
|
|
(id != null
|
|||
|
|
? "(id: " + esc(id) + ")"
|
|||
|
|
: "") +
|
|||
|
|
"</div>";
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
if (v.path.links && v.path.links.length) {
|
|||
|
|
html +=
|
|||
|
|
"<p class='count-hint'>链接 " +
|
|||
|
|
v.path.links.length +
|
|||
|
|
" 条</p>";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderBeneficiaries(v) {
|
|||
|
|
return itemList(v, function (b) {
|
|||
|
|
var pct = "-";
|
|||
|
|
if (b.percent != null && b.percent !== 0) {
|
|||
|
|
pct = (b.percent * 100).toFixed(1) + "%";
|
|||
|
|
}
|
|||
|
|
var title =
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(b.name) +
|
|||
|
|
(pct !== "-" ? "(" + pct + ")" : "") +
|
|||
|
|
"</div>";
|
|||
|
|
var parts = [];
|
|||
|
|
if (b.type) {
|
|||
|
|
parts.push("类型:" + esc(b.type));
|
|||
|
|
}
|
|||
|
|
if (b.reason) {
|
|||
|
|
parts.push("原因:" + esc(b.reason));
|
|||
|
|
}
|
|||
|
|
var meta =
|
|||
|
|
parts.length > 0
|
|||
|
|
? "<div class='item-meta'>" +
|
|||
|
|
parts.join(";") +
|
|||
|
|
"</div>"
|
|||
|
|
: "";
|
|||
|
|
return title + meta;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderInvestments(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无投资信息</p>";
|
|||
|
|
var html =
|
|||
|
|
"<h3>汇总</h3>" +
|
|||
|
|
kvTable(v, ["totalCount", "totalAmount"]);
|
|||
|
|
html +=
|
|||
|
|
"<h3>对外投资列表</h3>" +
|
|||
|
|
itemList(v.list || v.entities, function (inv) {
|
|||
|
|
var pct =
|
|||
|
|
inv.investPercent != null
|
|||
|
|
? (inv.investPercent * 100).toFixed(1)
|
|||
|
|
: "-";
|
|||
|
|
var title =
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(inv.entName) +
|
|||
|
|
"(" +
|
|||
|
|
pct +
|
|||
|
|
"%)</div>";
|
|||
|
|
var parts = [];
|
|||
|
|
if (inv.creditCode) {
|
|||
|
|
parts.push("信用代码:" + esc(inv.creditCode));
|
|||
|
|
}
|
|||
|
|
if (
|
|||
|
|
inv.investAmount != null &&
|
|||
|
|
inv.investAmount !== ""
|
|||
|
|
) {
|
|||
|
|
var amt =
|
|||
|
|
"投资额:" + esc(inv.investAmount) + " 万";
|
|||
|
|
if (inv.investCurrency) {
|
|||
|
|
amt +=
|
|||
|
|
"(单位:" +
|
|||
|
|
esc(inv.investCurrency) +
|
|||
|
|
")";
|
|||
|
|
}
|
|||
|
|
parts.push(amt);
|
|||
|
|
}
|
|||
|
|
if (inv.entStatus) {
|
|||
|
|
parts.push("状态:" + esc(inv.entStatus));
|
|||
|
|
}
|
|||
|
|
var meta =
|
|||
|
|
parts.length > 0
|
|||
|
|
? "<div class='item-meta'>" +
|
|||
|
|
parts.join(";") +
|
|||
|
|
"</div>"
|
|||
|
|
: "";
|
|||
|
|
return title + meta;
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>法定代表人个人对外投资</h3>" +
|
|||
|
|
itemList(
|
|||
|
|
v.legalRepresentativeInvestments ||
|
|||
|
|
v.legalPersonInvestments,
|
|||
|
|
function (inv) {
|
|||
|
|
var pct = "-";
|
|||
|
|
if (
|
|||
|
|
inv.investPercent != null &&
|
|||
|
|
Number(inv.investPercent) !== 0
|
|||
|
|
) {
|
|||
|
|
pct =
|
|||
|
|
(inv.investPercent * 100).toFixed(1) +
|
|||
|
|
"%";
|
|||
|
|
}
|
|||
|
|
var title =
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(inv.entName) +
|
|||
|
|
(pct !== "-" ? "(" + pct + ")" : "") +
|
|||
|
|
"</div>";
|
|||
|
|
var parts = [];
|
|||
|
|
if (inv.creditCode) {
|
|||
|
|
parts.push(
|
|||
|
|
"信用代码:" + esc(inv.creditCode),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
// 优先展示投资额,其次在无投资额但有注册资本时展示注册资本
|
|||
|
|
if (
|
|||
|
|
inv.investAmount != null &&
|
|||
|
|
inv.investAmount !== "" &&
|
|||
|
|
Number(inv.investAmount) !== 0
|
|||
|
|
) {
|
|||
|
|
parts.push(
|
|||
|
|
"投资额:" +
|
|||
|
|
esc(inv.investAmount) +
|
|||
|
|
" 万",
|
|||
|
|
);
|
|||
|
|
} else if (
|
|||
|
|
inv.regCap != null &&
|
|||
|
|
inv.regCap !== "" &&
|
|||
|
|
Number(inv.regCap) !== 0
|
|||
|
|
) {
|
|||
|
|
parts.push(
|
|||
|
|
"注册资本:" +
|
|||
|
|
esc(inv.regCap) +
|
|||
|
|
" 万(企业注册资本)",
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
if (inv.entStatus) {
|
|||
|
|
parts.push("状态:" + esc(inv.entStatus));
|
|||
|
|
}
|
|||
|
|
var meta =
|
|||
|
|
parts.length > 0
|
|||
|
|
? "<div class='item-meta'>" +
|
|||
|
|
parts.join(";") +
|
|||
|
|
"</div>"
|
|||
|
|
: "";
|
|||
|
|
return title + meta;
|
|||
|
|
},
|
|||
|
|
);
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderGuarantees(v) {
|
|||
|
|
if (!Array.isArray(v) || !v.length) {
|
|||
|
|
return "<p class='empty-hint'>暂无对外担保信息</p>";
|
|||
|
|
}
|
|||
|
|
// 只展示有关键字段的记录,避免一堆空行
|
|||
|
|
var coreKeys = [
|
|||
|
|
"mortgagor",
|
|||
|
|
"creditor",
|
|||
|
|
"principalAmount",
|
|||
|
|
"principalKind",
|
|||
|
|
"guaranteeType",
|
|||
|
|
"periodFrom",
|
|||
|
|
"periodTo",
|
|||
|
|
];
|
|||
|
|
var list = v.filter(function (g) {
|
|||
|
|
return coreKeys.some(function (k) {
|
|||
|
|
return g[k] != null && g[k] !== "";
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
if (!list.length) {
|
|||
|
|
return (
|
|||
|
|
"<p class='empty-hint'>存在 " +
|
|||
|
|
v.length +
|
|||
|
|
" 条年报披露的对外担保记录,但债务人、债权人等关键字段为空,暂无法展示详细明细。</p>"
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
return (
|
|||
|
|
"<p class='count-hint'>共 " +
|
|||
|
|
list.length +
|
|||
|
|
" 条(年报披露)</p>" +
|
|||
|
|
itemList(list, function (g) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(g.mortgagor || "-") +
|
|||
|
|
" → " +
|
|||
|
|
esc(g.creditor || "-") +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>主债权数额:" +
|
|||
|
|
esc(g.principalAmount || "-") +
|
|||
|
|
";种类:" +
|
|||
|
|
esc(g.principalKind || "-") +
|
|||
|
|
";保证方式:" +
|
|||
|
|
esc(g.guaranteeType || "-") +
|
|||
|
|
";期限:" +
|
|||
|
|
esc(g.periodFrom || "-") +
|
|||
|
|
" 至 " +
|
|||
|
|
esc(g.periodTo || "-") +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
})
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderManagement(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无人员信息</p>";
|
|||
|
|
var html =
|
|||
|
|
"<h3>高管列表</h3>" +
|
|||
|
|
itemList(v.executives, function (e) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(e.name) +
|
|||
|
|
"</div><div class='item-meta'>" +
|
|||
|
|
esc(formatPosition(e.position)) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>从业与社保</h3>" +
|
|||
|
|
kvTable(v, [
|
|||
|
|
"employeeCount",
|
|||
|
|
"femaleEmployeeCount",
|
|||
|
|
"socialSecurity",
|
|||
|
|
]);
|
|||
|
|
html += "<h3>法定代表人其他任职</h3>";
|
|||
|
|
var others =
|
|||
|
|
v.legalRepresentativeOtherPositions ||
|
|||
|
|
v.legalPersonOtherPositions;
|
|||
|
|
html += itemList(others, function (f) {
|
|||
|
|
var title =
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(f.entName) +
|
|||
|
|
"</div>";
|
|||
|
|
var parts = [];
|
|||
|
|
if (f.position) {
|
|||
|
|
parts.push(
|
|||
|
|
"职务:" + esc(formatPosition(f.position)),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
if (f.name) {
|
|||
|
|
parts.push("姓名:" + esc(f.name));
|
|||
|
|
}
|
|||
|
|
if (f.entStatus) {
|
|||
|
|
parts.push("企业状态:" + esc(f.entStatus));
|
|||
|
|
}
|
|||
|
|
if (f.creditCode) {
|
|||
|
|
parts.push("信用代码:" + esc(f.creditCode));
|
|||
|
|
}
|
|||
|
|
if (f.regNo) {
|
|||
|
|
parts.push("注册号:" + esc(f.regNo));
|
|||
|
|
}
|
|||
|
|
var meta =
|
|||
|
|
parts.length > 0
|
|||
|
|
? "<div class='item-meta'>" +
|
|||
|
|
parts.join(";") +
|
|||
|
|
"</div>"
|
|||
|
|
: "";
|
|||
|
|
return title + meta;
|
|||
|
|
});
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderAssets(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无资产数据</p>";
|
|||
|
|
var years = Array.isArray(v.years) ? v.years : [];
|
|||
|
|
if (!years.length)
|
|||
|
|
return "<p class='empty-hint'>暂无资产数据</p>";
|
|||
|
|
// 过滤掉所有核心字段都为空的年度记录,避免一堆空行
|
|||
|
|
var coreKeys = [
|
|||
|
|
"assetTotal",
|
|||
|
|
"revenueTotal",
|
|||
|
|
"netProfit",
|
|||
|
|
"liabilityTotal",
|
|||
|
|
"equityTotal",
|
|||
|
|
"profitTotal",
|
|||
|
|
];
|
|||
|
|
var list = years.filter(function (y) {
|
|||
|
|
return coreKeys.some(function (k) {
|
|||
|
|
return y[k] != null && y[k] !== "";
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
if (!list.length) {
|
|||
|
|
return "<p class='empty-hint'>存在年报资产经营记录,但资产总额、营收、净利润等核心字段为空,暂无法展示详细明细。</p>";
|
|||
|
|
}
|
|||
|
|
return (
|
|||
|
|
"<h3>按年度资产经营数据</h3>" +
|
|||
|
|
itemList(list, function (y) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(y.year) +
|
|||
|
|
" " +
|
|||
|
|
esc(y.reportDate || "") +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>资产总额:" +
|
|||
|
|
esc(y.assetTotal || "-") +
|
|||
|
|
";营收:" +
|
|||
|
|
esc(y.revenueTotal || "-") +
|
|||
|
|
";净利润:" +
|
|||
|
|
esc(y.netProfit || "-") +
|
|||
|
|
";负债:" +
|
|||
|
|
esc(y.liabilityTotal || "-") +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
})
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderLicenses(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无许可信息</p>";
|
|||
|
|
var html =
|
|||
|
|
"<h3>行政许可列表</h3>" +
|
|||
|
|
itemList(v.permits, function (p) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(p.name) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>有效期:" +
|
|||
|
|
esc(p.valFrom) +
|
|||
|
|
" ~ " +
|
|||
|
|
esc(p.valTo) +
|
|||
|
|
";许可机关:" +
|
|||
|
|
esc(p.licAnth) +
|
|||
|
|
";" +
|
|||
|
|
esc(p.licItem) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>许可变更记录</h3>" +
|
|||
|
|
itemList(v.permitChanges, function (p) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(p.changeDate) +
|
|||
|
|
" " +
|
|||
|
|
esc(p.changeType) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>变更前:" +
|
|||
|
|
(p.detailBefore || "-").substring(0, 80) +
|
|||
|
|
"…;变更后:" +
|
|||
|
|
(p.detailAfter || "-").substring(0, 80) +
|
|||
|
|
"…</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>知识产权出质</h3>" +
|
|||
|
|
itemList(v.ipPledges, function (i) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-block'>" +
|
|||
|
|
(typeof i === "object"
|
|||
|
|
? JSON.stringify(i)
|
|||
|
|
: esc(i)) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderActivities(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无经营活动数据</p>";
|
|||
|
|
// 招投标:对角色、类型做友好映射
|
|||
|
|
var bidRoleMap = {
|
|||
|
|
10: "招标人/采购人",
|
|||
|
|
20: "中标人/供应商",
|
|||
|
|
30: "代理机构",
|
|||
|
|
};
|
|||
|
|
var announceTypeMap = {
|
|||
|
|
10: "招标公告",
|
|||
|
|
20: "中标结果公告",
|
|||
|
|
};
|
|||
|
|
var html =
|
|||
|
|
"<h3>招投标</h3>" +
|
|||
|
|
itemList(v.bids, function (b) {
|
|||
|
|
var t =
|
|||
|
|
b.announcetitle ||
|
|||
|
|
b.ANNOUNCETITLE ||
|
|||
|
|
b.title ||
|
|||
|
|
"-";
|
|||
|
|
var roleCode = b.bidrole || b.BIDROLE;
|
|||
|
|
var roleText =
|
|||
|
|
bidRoleMap[Number(roleCode)] ||
|
|||
|
|
(roleCode != null && roleCode !== ""
|
|||
|
|
? "角色代码:" + roleCode
|
|||
|
|
: "-");
|
|||
|
|
var typeCode =
|
|||
|
|
b.announceType ||
|
|||
|
|
b.annoucetype ||
|
|||
|
|
b.ANNOUNCETYPE;
|
|||
|
|
var typeText =
|
|||
|
|
announceTypeMap[Number(typeCode)] ||
|
|||
|
|
(typeCode != null && typeCode !== ""
|
|||
|
|
? "类型代码:" + typeCode
|
|||
|
|
: "-");
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(t) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>角色:" +
|
|||
|
|
esc(roleText) +
|
|||
|
|
";类型:" +
|
|||
|
|
esc(typeText) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>网站/网店</h3>" +
|
|||
|
|
itemList(v.websites, function (w) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(w.websitname || w.WEBSITNAME || w.name) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>类型:" +
|
|||
|
|
esc(w.webtype || w.WEBTYPE) +
|
|||
|
|
";域名:" +
|
|||
|
|
esc(w.domain || w.DOMAIN) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderInspections(v) {
|
|||
|
|
return itemList(v, function (i) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(i.inspectDate) +
|
|||
|
|
" " +
|
|||
|
|
esc(i.result) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>数据类型:" +
|
|||
|
|
esc(i.dataType) +
|
|||
|
|
";检查机关:" +
|
|||
|
|
esc(i.regOrg) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderRisks(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无风险数据</p>";
|
|||
|
|
var hasKeys = [
|
|||
|
|
"hasCourtJudgments",
|
|||
|
|
"hasJudicialAssists",
|
|||
|
|
"hasDishonestDebtors",
|
|||
|
|
"hasLimitHighDebtors",
|
|||
|
|
"hasAdminPenalty",
|
|||
|
|
"hasException",
|
|||
|
|
"hasSeriousIllegal",
|
|||
|
|
"hasTaxOwing",
|
|||
|
|
"hasSeriousTaxIllegal",
|
|||
|
|
"hasMortgage",
|
|||
|
|
"hasEquityPledges",
|
|||
|
|
"hasQuickCancel",
|
|||
|
|
];
|
|||
|
|
var hasLabels = [
|
|||
|
|
"裁判文书",
|
|||
|
|
"司法协助",
|
|||
|
|
"失信被执行人",
|
|||
|
|
"限高被执行人",
|
|||
|
|
"行政处罚",
|
|||
|
|
"经营异常",
|
|||
|
|
"严重违法",
|
|||
|
|
"欠税",
|
|||
|
|
"重大税收违法",
|
|||
|
|
"动产抵押",
|
|||
|
|
"股权出质",
|
|||
|
|
"简易注销",
|
|||
|
|
];
|
|||
|
|
var html = "<h3>风险项</h3><ul class='item-list'>";
|
|||
|
|
hasKeys.forEach(function (k, idx) {
|
|||
|
|
var val = v[k];
|
|||
|
|
if (val === undefined)
|
|||
|
|
val =
|
|||
|
|
v[
|
|||
|
|
k
|
|||
|
|
.replace("Judgments", "JudicialCase")
|
|||
|
|
.replace("Assists", "JudicialAid")
|
|||
|
|
.replace("EquityPledges", "StockPawn")
|
|||
|
|
];
|
|||
|
|
html +=
|
|||
|
|
"<li class='risk-row'><span>" +
|
|||
|
|
hasLabels[idx] +
|
|||
|
|
"</span><span class='" +
|
|||
|
|
(val ? "bad" : "ok") +
|
|||
|
|
"'>" +
|
|||
|
|
(val ? "存在" : "未发现") +
|
|||
|
|
"</span></li>";
|
|||
|
|
});
|
|||
|
|
html += "</ul>";
|
|||
|
|
html +=
|
|||
|
|
"<h3>裁判文书</h3>" +
|
|||
|
|
itemList(
|
|||
|
|
v.courtJudgments || v.judicialCases,
|
|||
|
|
function (c) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(
|
|||
|
|
c.caseNumber ||
|
|||
|
|
c.CASENUMBER ||
|
|||
|
|
c.judicialDocumentId,
|
|||
|
|
) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>案由:" +
|
|||
|
|
esc(c.caseCause || c.CASECAUSE) +
|
|||
|
|
";结果:" +
|
|||
|
|
esc(c.judgeResult || c.JUDGERESULT) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
},
|
|||
|
|
);
|
|||
|
|
html +=
|
|||
|
|
"<h3>司法协助</h3>" +
|
|||
|
|
itemList(
|
|||
|
|
v.judicialAssists || v.judicialAids,
|
|||
|
|
function (a) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(a.iname || a.INAME || a.marketName) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>法院:" +
|
|||
|
|
esc(a.courtName || a.COURTNAME) +
|
|||
|
|
";股权数额:" +
|
|||
|
|
esc(a.shaream || a.SHAREAM) +
|
|||
|
|
" 元</div>"
|
|||
|
|
);
|
|||
|
|
},
|
|||
|
|
);
|
|||
|
|
html +=
|
|||
|
|
"<h3>失信被执行人</h3>" +
|
|||
|
|
itemList(v.dishonestDebtors, function (d) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>案号 " +
|
|||
|
|
esc(d.caseNo) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>执行法院:" +
|
|||
|
|
esc(d.execCourt) +
|
|||
|
|
";履行情况:" +
|
|||
|
|
esc(d.performanceStatus) +
|
|||
|
|
";发布时间:" +
|
|||
|
|
esc(d.publishDate) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>限高被执行人</h3>" +
|
|||
|
|
itemList(v.limitHighDebtors, function (x) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(x.ah || x.caseNo) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>执行法院:" +
|
|||
|
|
esc(x.zxfy || x.execCourt) +
|
|||
|
|
";" +
|
|||
|
|
esc(x.fbrq || x.publishDate) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
// 按案件类型展示涉诉信息(来自企业司法认证 entout)
|
|||
|
|
if (v.litigation && v.litigation.totalCases) {
|
|||
|
|
var lit = v.litigation;
|
|||
|
|
var typeLabels = {
|
|||
|
|
administrative: "行政案件",
|
|||
|
|
implement: "执行案件",
|
|||
|
|
preservation: "非诉保全审查",
|
|||
|
|
civil: "民事案件",
|
|||
|
|
criminal: "刑事案件",
|
|||
|
|
bankrupt: "强制清算与破产案件",
|
|||
|
|
jurisdict: "管辖案件",
|
|||
|
|
compensate: "赔偿案件",
|
|||
|
|
};
|
|||
|
|
html += "<h3>涉诉案件汇总</h3>";
|
|||
|
|
var rows = [];
|
|||
|
|
Object.keys(typeLabels).forEach(function (k) {
|
|||
|
|
var sec = lit[k];
|
|||
|
|
if (sec && sec.count) {
|
|||
|
|
rows.push({
|
|||
|
|
k: typeLabels[k],
|
|||
|
|
v: sec.count + " 件",
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
if (rows.length) {
|
|||
|
|
html +=
|
|||
|
|
"<table class='kv-table'><tbody>" +
|
|||
|
|
rows
|
|||
|
|
.map(function (r) {
|
|||
|
|
return (
|
|||
|
|
"<tr><th>" +
|
|||
|
|
esc(r.k) +
|
|||
|
|
"</th><td>" +
|
|||
|
|
esc(r.v) +
|
|||
|
|
"</td></tr>"
|
|||
|
|
);
|
|||
|
|
})
|
|||
|
|
.join("") +
|
|||
|
|
"</tbody></table>";
|
|||
|
|
}
|
|||
|
|
Object.keys(typeLabels).forEach(function (k) {
|
|||
|
|
var sec = lit[k];
|
|||
|
|
if (!sec || !sec.cases || !sec.cases.length) return;
|
|||
|
|
html +=
|
|||
|
|
"<h3>" +
|
|||
|
|
typeLabels[k] +
|
|||
|
|
"</h3>" +
|
|||
|
|
itemList(sec.cases, function (c) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(c.caseNo) +
|
|||
|
|
"(" +
|
|||
|
|
esc(c.court) +
|
|||
|
|
")</div>" +
|
|||
|
|
"<div class='item-meta'>" +
|
|||
|
|
"地区:" +
|
|||
|
|
esc(c.region) +
|
|||
|
|
";审级:" +
|
|||
|
|
esc(c.trialLevel) +
|
|||
|
|
";案件类型:" +
|
|||
|
|
esc(c.caseType) +
|
|||
|
|
";案由:" +
|
|||
|
|
esc(c.cause) +
|
|||
|
|
";标的金额:" +
|
|||
|
|
esc(c.amount) +
|
|||
|
|
";立案日期:" +
|
|||
|
|
esc(c.filingDate) +
|
|||
|
|
";裁判日期:" +
|
|||
|
|
esc(c.judgmentDate) +
|
|||
|
|
";胜败结果:" +
|
|||
|
|
esc(c.victoryResult) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
html +=
|
|||
|
|
"<h3>行政处罚</h3>" +
|
|||
|
|
itemList(v.adminPenalties, function (p) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(p.pendecno || p.PENDECNO) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>违法类型:" +
|
|||
|
|
esc(p.illegacttype || p.ILLEGACTTYPE) +
|
|||
|
|
";机关:" +
|
|||
|
|
esc(p.penauth || p.PENAUTH) +
|
|||
|
|
";日期:" +
|
|||
|
|
esc(p.pendecissdate || p.PENDECISSDATE) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>行政处罚变更记录</h3>" +
|
|||
|
|
itemList(v.adminPenaltyUpdates, function (p) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(p.updateDate) +
|
|||
|
|
"</div><div class='item-meta'>" +
|
|||
|
|
esc(p.updateContent) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>经营异常</h3>" +
|
|||
|
|
itemList(v.exceptions, function (e) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(e.indate || e.INDATE) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>原因:" +
|
|||
|
|
esc(e.inreason || e.INREASON) +
|
|||
|
|
";移出:" +
|
|||
|
|
esc(e.outdate || e.OUTDATE) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>严重违法</h3>" +
|
|||
|
|
itemList(v.seriousIllegals, function (s) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-block'>" +
|
|||
|
|
(typeof s === "object"
|
|||
|
|
? JSON.stringify(s)
|
|||
|
|
: esc(s)) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>动产抵押</h3>" +
|
|||
|
|
itemList(v.mortgages, function (m) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(m.regNo) +
|
|||
|
|
" " +
|
|||
|
|
esc(m.guaranteedAmount) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>登记日:" +
|
|||
|
|
esc(m.regDate) +
|
|||
|
|
";机关:" +
|
|||
|
|
esc(m.regOrg) +
|
|||
|
|
";状态:" +
|
|||
|
|
esc(m.status) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html += "<h3>简易注销</h3>";
|
|||
|
|
if (v.quickCancel) {
|
|||
|
|
html += kvTable(v.quickCancel, [
|
|||
|
|
"entName",
|
|||
|
|
"creditCode",
|
|||
|
|
"regNo",
|
|||
|
|
"regOrg",
|
|||
|
|
"noticeFromDate",
|
|||
|
|
"noticeToDate",
|
|||
|
|
"cancelResult",
|
|||
|
|
]);
|
|||
|
|
if (
|
|||
|
|
v.quickCancel.dissents &&
|
|||
|
|
v.quickCancel.dissents.length
|
|||
|
|
) {
|
|||
|
|
html +=
|
|||
|
|
"<p class='count-hint'>异议 " +
|
|||
|
|
v.quickCancel.dissents.length +
|
|||
|
|
" 条</p>";
|
|||
|
|
v.quickCancel.dissents.forEach(function (d) {
|
|||
|
|
html +=
|
|||
|
|
"<div class='item-block'>" +
|
|||
|
|
esc(d.dissentOrg) +
|
|||
|
|
":" +
|
|||
|
|
esc(d.dissentDes) +
|
|||
|
|
" " +
|
|||
|
|
esc(d.dissentDate) +
|
|||
|
|
"</div>";
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
html += "<p class='empty-hint'>无</p>";
|
|||
|
|
}
|
|||
|
|
html += "<h3>清算信息</h3>";
|
|||
|
|
if (v.liquidation) {
|
|||
|
|
html += kvTable(v.liquidation, [
|
|||
|
|
"principal",
|
|||
|
|
"members",
|
|||
|
|
]);
|
|||
|
|
} else {
|
|||
|
|
html += "<p class='empty-hint'>无</p>";
|
|||
|
|
}
|
|||
|
|
html += "<h3>纳税与欠税</h3>";
|
|||
|
|
var tax = v.taxRecords;
|
|||
|
|
if (tax) {
|
|||
|
|
html +=
|
|||
|
|
"<p class='count-hint'>纳税A级年度:" +
|
|||
|
|
(tax.taxLevelAYears && tax.taxLevelAYears.length
|
|||
|
|
? tax.taxLevelAYears.length + " 条"
|
|||
|
|
: "无") +
|
|||
|
|
";欠税:" +
|
|||
|
|
(tax.taxOwings && tax.taxOwings.length
|
|||
|
|
? tax.taxOwings.length + " 条"
|
|||
|
|
: "无") +
|
|||
|
|
"</p>";
|
|||
|
|
html += itemList(tax.taxOwings, function (t) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(t.taxOwedType || t.taxowedtype) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>合计:" +
|
|||
|
|
esc(t.totalOwedAmount || t.totalowedamount) +
|
|||
|
|
";公示日:" +
|
|||
|
|
esc(t.publishDate || t.publishdate) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
html += "<p class='empty-hint'>无</p>";
|
|||
|
|
}
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderRiskOverview(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无风险分析</p>";
|
|||
|
|
var html = "";
|
|||
|
|
// 风险点清单:命中 / 未命中,多列展示
|
|||
|
|
if (Array.isArray(v.items) && v.items.length) {
|
|||
|
|
html += "<h3>风险点一览</h3>";
|
|||
|
|
html += "<div class='risk-points-grid'>";
|
|||
|
|
v.items.forEach(function (it) {
|
|||
|
|
var statusText = it.hit ? "命中" : "未命中";
|
|||
|
|
var statusClass = it.hit
|
|||
|
|
? "risk-status-bad"
|
|||
|
|
: "risk-status-ok";
|
|||
|
|
html +=
|
|||
|
|
"<div class='risk-point'><span class='risk-point-name'>" +
|
|||
|
|
esc(it.name) +
|
|||
|
|
"</span><span class='" +
|
|||
|
|
statusClass +
|
|||
|
|
"'>" +
|
|||
|
|
statusText +
|
|||
|
|
"</span></div>";
|
|||
|
|
});
|
|||
|
|
html += "</div>";
|
|||
|
|
}
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderTimeline(v) {
|
|||
|
|
if (!v || !v.length)
|
|||
|
|
return "<p class='empty-hint'>暂无发展时间线</p>";
|
|||
|
|
return itemList(v, function (item) {
|
|||
|
|
var title =
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(item.date) +
|
|||
|
|
" " +
|
|||
|
|
esc(item.type) +
|
|||
|
|
"</div>";
|
|||
|
|
var body = "<div>" + esc(item.title || "") + "</div>";
|
|||
|
|
var meta = "";
|
|||
|
|
if (item.detailBefore || item.detailAfter) {
|
|||
|
|
// 对长文本拆成更易读的多行段落
|
|||
|
|
var before = (item.detailBefore || "")
|
|||
|
|
.replace(/;/g, ";<br/>")
|
|||
|
|
.replace(/;;+/g, ";");
|
|||
|
|
var after = (item.detailAfter || "")
|
|||
|
|
.replace(/;/g, ";<br/>")
|
|||
|
|
.replace(/;;+/g, ";");
|
|||
|
|
meta =
|
|||
|
|
"<div class='item-meta'>" +
|
|||
|
|
"<div><strong>变更前:</strong><br/>" +
|
|||
|
|
before +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div style='margin-top:4px'><strong>变更后:</strong><br/>" +
|
|||
|
|
after +
|
|||
|
|
"</div>" +
|
|||
|
|
"</div>";
|
|||
|
|
}
|
|||
|
|
return title + body + meta;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderListed(v) {
|
|||
|
|
if (!v)
|
|||
|
|
return "<p class='empty-hint'>非上市或暂无上市信息</p>";
|
|||
|
|
var html =
|
|||
|
|
"<h3>是否上市</h3><p>" +
|
|||
|
|
(v.isListed ? "是" : "否") +
|
|||
|
|
"</p>";
|
|||
|
|
if (v.company) {
|
|||
|
|
html +=
|
|||
|
|
"<h3>上市公司信息</h3>" +
|
|||
|
|
kvTable(v.company, [
|
|||
|
|
"bizScope",
|
|||
|
|
"creditCode",
|
|||
|
|
"regAddr",
|
|||
|
|
"regCapital",
|
|||
|
|
"orgCode",
|
|||
|
|
"cur",
|
|||
|
|
"curName",
|
|||
|
|
]);
|
|||
|
|
}
|
|||
|
|
html += "<h3>股票信息</h3>";
|
|||
|
|
if (v.stock)
|
|||
|
|
html +=
|
|||
|
|
"<div class='item-block'>" +
|
|||
|
|
(typeof v.stock === "object"
|
|||
|
|
? JSON.stringify(v.stock)
|
|||
|
|
: esc(v.stock)) +
|
|||
|
|
"</div>";
|
|||
|
|
else html += "<p class='empty-hint'>无</p>";
|
|||
|
|
html +=
|
|||
|
|
"<h3>十大股东</h3>" +
|
|||
|
|
itemList(v.topShareholders, function (s) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(s.name || s.shaname) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>" +
|
|||
|
|
esc(s.percent || s.fundedratio) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
html +=
|
|||
|
|
"<h3>上市高管</h3>" +
|
|||
|
|
itemList(v.listedManagers, function (m) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(m.name || m.perName) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>" +
|
|||
|
|
esc(m.position) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderScores(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>暂无评分</p>";
|
|||
|
|
var html = kvTable(v, [
|
|||
|
|
"overallScore",
|
|||
|
|
"stabilityScore",
|
|||
|
|
"equityTransparencyScore",
|
|||
|
|
"complianceScore",
|
|||
|
|
"activityScore",
|
|||
|
|
]);
|
|||
|
|
if (v.tags && v.tags.length) {
|
|||
|
|
html += "<h3>标签</h3><p>";
|
|||
|
|
v.tags.forEach(function (t) {
|
|||
|
|
html += "<span class='tag'>" + esc(t) + "</span> ";
|
|||
|
|
});
|
|||
|
|
html += "</p>";
|
|||
|
|
}
|
|||
|
|
return html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderBasicList(v) {
|
|||
|
|
return itemList(v, function (b) {
|
|||
|
|
return (
|
|||
|
|
"<div class='item-title'>" +
|
|||
|
|
esc(b.entName || b.entname) +
|
|||
|
|
"</div>" +
|
|||
|
|
"<div class='item-meta'>信用代码:" +
|
|||
|
|
esc(b.creditCode || b.creditNo || b.creditno) +
|
|||
|
|
";注册号:" +
|
|||
|
|
esc(b.regNo) +
|
|||
|
|
"</div>"
|
|||
|
|
);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function renderRaw(v) {
|
|||
|
|
if (!v) return "<p class='empty-hint'>无原始数据</p>";
|
|||
|
|
return (
|
|||
|
|
"<details class='raw-section'><summary>展开 jiguangFull / judicialCertFull</summary>" +
|
|||
|
|
"<pre>" +
|
|||
|
|
esc(JSON.stringify(v, null, 2)).substring(0, 15000) +
|
|||
|
|
(JSON.stringify(v).length > 15000
|
|||
|
|
? "\n…(已截断)"
|
|||
|
|
: "") +
|
|||
|
|
"</pre></details>"
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var sectionRenderers = {
|
|||
|
|
riskOverview: renderRiskOverview,
|
|||
|
|
basic: renderBasic,
|
|||
|
|
branches: renderBranches,
|
|||
|
|
shareholding: renderShareholding,
|
|||
|
|
controller: renderController,
|
|||
|
|
beneficiaries: renderBeneficiaries,
|
|||
|
|
investments: renderInvestments,
|
|||
|
|
guarantees: renderGuarantees,
|
|||
|
|
management: renderManagement,
|
|||
|
|
assets: renderAssets,
|
|||
|
|
licenses: renderLicenses,
|
|||
|
|
activities: renderActivities,
|
|||
|
|
inspections: renderInspections,
|
|||
|
|
risks: renderRisks,
|
|||
|
|
timeline: renderTimeline,
|
|||
|
|
listed: renderListed,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function renderSectionContent(key, value) {
|
|||
|
|
var fn = sectionRenderers[key];
|
|||
|
|
if (fn) return fn(value);
|
|||
|
|
if (value == null)
|
|||
|
|
return "<p class='empty-hint'>暂无数据</p>";
|
|||
|
|
if (Array.isArray(value))
|
|||
|
|
return itemList(value, function (item) {
|
|||
|
|
return typeof item === "object"
|
|||
|
|
? "<div class='item-block'>" +
|
|||
|
|
kvTable(item, Object.keys(item)) +
|
|||
|
|
"</div>"
|
|||
|
|
: esc(item);
|
|||
|
|
});
|
|||
|
|
if (typeof value === "object")
|
|||
|
|
return kvTable(value, Object.keys(value));
|
|||
|
|
return "<p>" + esc(value) + "</p>";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function render() {
|
|||
|
|
var d = reportData;
|
|||
|
|
document.getElementById("entName").textContent =
|
|||
|
|
d.entName || "企业名称";
|
|||
|
|
document.getElementById("creditCodeLabel").textContent =
|
|||
|
|
"统一社会信用代码:" + (d.creditCode || "-");
|
|||
|
|
document.getElementById("entStatusLabel").textContent =
|
|||
|
|
"经营状态:" +
|
|||
|
|
((d.basic && (d.basic.status || d.basic.entStatus)) ||
|
|||
|
|
"-");
|
|||
|
|
document.getElementById("entTypeLabel").textContent =
|
|||
|
|
"企业类型:" + ((d.basic && d.basic.entType) || "-");
|
|||
|
|
document.getElementById("reportTimeLabel").textContent =
|
|||
|
|
"报告生成时间:" + (d.reportTime || "-");
|
|||
|
|
// 使用 riskOverview 中的风险得分和等级替换原综合评分
|
|||
|
|
var ro = d.riskOverview || {};
|
|||
|
|
document.getElementById("overallScore").textContent =
|
|||
|
|
ro.riskScore != null ? ro.riskScore : "-";
|
|||
|
|
var level = ro.riskLevel || "-";
|
|||
|
|
var pill = document.getElementById("riskLevelPill");
|
|||
|
|
pill.textContent = "风险:" + level;
|
|||
|
|
pill.className = "pill low";
|
|||
|
|
if (level === "中") pill.classList.add("mid");
|
|||
|
|
else if (level === "高") pill.classList.add("high");
|
|||
|
|
var tagsBox = document.getElementById("headerTags");
|
|||
|
|
tagsBox.innerHTML = "";
|
|||
|
|
(ro.tags || []).forEach(function (t) {
|
|||
|
|
var span = document.createElement("span");
|
|||
|
|
span.className = "tag";
|
|||
|
|
span.textContent = t;
|
|||
|
|
tagsBox.appendChild(span);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var nav = document.getElementById("navLinks");
|
|||
|
|
nav.innerHTML = "";
|
|||
|
|
sectionOrder.forEach(function (key) {
|
|||
|
|
if (key === "raw") return;
|
|||
|
|
var a = document.createElement("a");
|
|||
|
|
a.href = "#section-" + key;
|
|||
|
|
a.textContent = sectionTitles[key] || key;
|
|||
|
|
nav.appendChild(a);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var container = document.getElementById("reportSections");
|
|||
|
|
container.innerHTML = "";
|
|||
|
|
sectionOrder.forEach(function (key) {
|
|||
|
|
var value = d[key];
|
|||
|
|
var card = document.createElement("div");
|
|||
|
|
card.className = "section-card";
|
|||
|
|
card.id = "section-" + key;
|
|||
|
|
var title = document.createElement("h2");
|
|||
|
|
title.textContent = sectionTitles[key] || key;
|
|||
|
|
card.appendChild(title);
|
|||
|
|
var body = document.createElement("div");
|
|||
|
|
body.className = "section-body";
|
|||
|
|
body.innerHTML = renderSectionContent(key, value);
|
|||
|
|
card.appendChild(body);
|
|||
|
|
container.appendChild(card);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function loadReport() {
|
|||
|
|
try {
|
|||
|
|
// 使用后端注入的 reportData 直接渲染
|
|||
|
|
if (!reportData || typeof reportData !== "object") {
|
|||
|
|
reportData = {
|
|||
|
|
entName: "未加载到数据",
|
|||
|
|
basic: {},
|
|||
|
|
risks: {},
|
|||
|
|
riskOverview: {},
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
render();
|
|||
|
|
} catch (e) {
|
|||
|
|
console.error("渲染企业报告失败", e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
loadReport();
|
|||
|
|
})();
|
|||
|
|
</script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|