Compare commits
32 Commits
87aac154cf
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ac2fdd095 | |||
| 73fff791dc | |||
| 15e2c24be1 | |||
| bd639ba66c | |||
| a6517f1ea1 | |||
| a5d9de5736 | |||
| b2da12f3ed | |||
| 9937097d7c | |||
| 2df104acea | |||
| 02fdc45879 | |||
| f0206916be | |||
| de69a9d58c | |||
| 684601ffe8 | |||
| 9bb7c4ddae | |||
| d97f27a124 | |||
| 6e3dc2cd75 | |||
| b8b24896b3 | |||
| 51ad490293 | |||
| 82ea7ebee8 | |||
| 2aa2090c82 | |||
| 50050219fe | |||
| 571fee6088 | |||
| c6a9c8d342 | |||
| 94d00ac822 | |||
| 5947beb244 | |||
| bf67fa8193 | |||
| 278656d9f2 | |||
| fa70627e90 | |||
| b0ccfa924e | |||
| 1b27ee4203 | |||
| ae247daf44 | |||
| c0fc989c8f |
36
index.html
36
index.html
@@ -14,15 +14,15 @@
|
|||||||
|
|
||||||
<!-- 基础SEO信息 -->
|
<!-- 基础SEO信息 -->
|
||||||
<title>
|
<title>
|
||||||
天远数据|大数据风险报告查询与代理平台,支持个人和企业多场景风控应用
|
天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台
|
||||||
</title>
|
</title>
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="天远数据,专业大数据风险报告查询与代理平台,支持个人信用查询、小微企业风控、贷前风险背调等多场景报告应用,免费开通代理权限,助力高效识别信用与风险。"
|
content="天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。"
|
||||||
/>
|
/>
|
||||||
<meta
|
<meta
|
||||||
name="keywords"
|
name="keywords"
|
||||||
content="大数据风险报告查询、大数据风险评估、大数据分析报告、个人大数据风险查询、小微企业风险、贷前风险背调、代理管理平台、免费开通代理、风险管控平台、信用风险分析、企业风险报告、贷前信用审核、失信人名单查询、被执行人信息、信用黑名单查询"
|
content="天远数据,职场背调,风险核验报告,家政背景核验,第三方背调,企业风控服务,数据报告分销"
|
||||||
/>
|
/>
|
||||||
<meta name="author" content="天远数据" />
|
<meta name="author" content="天远数据" />
|
||||||
<meta name="robots" content="index, follow" />
|
<meta name="robots" content="index, follow" />
|
||||||
@@ -31,17 +31,17 @@
|
|||||||
|
|
||||||
<!-- Open Graph / Facebook -->
|
<!-- Open Graph / Facebook -->
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:url" content="https://www.zhinengcha.cn/" />
|
<meta property="og:url" content="https://www.tianyuandb.com/" />
|
||||||
<meta property="og:title" content="天远数据|大数据风险报告查询与代理平台,支持个人和企业多场景风控应用" />
|
<meta property="og:title" content="天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台" />
|
||||||
<meta property="og:description" content="天远数据,专业大数据风险报告查询与代理平台,支持个人信用查询、小微企业风控、贷前风险背调等多场景报告应用,免费开通代理权限,助力高效识别信用与风险。" />
|
<meta property="og:description" content="天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。" />
|
||||||
<meta property="og:site_name" content="天远数据" />
|
<meta property="og:site_name" content="天远数据" />
|
||||||
<meta property="og:locale" content="zh_CN" />
|
<meta property="og:locale" content="zh_CN" />
|
||||||
|
|
||||||
<!-- Twitter -->
|
<!-- Twitter -->
|
||||||
<meta property="twitter:card" content="summary" />
|
<meta property="twitter:card" content="summary" />
|
||||||
<meta property="twitter:url" content="https://www.zhinengcha.cn/" />
|
<meta property="twitter:url" content="https://www.tianyuandb.com/" />
|
||||||
<meta property="twitter:title" content="天远数据|大数据风险报告查询与代理平台,支持个人和企业多场景风控应用" />
|
<meta property="twitter:title" content="天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台" />
|
||||||
<meta property="twitter:description" content="天远数据,专业大数据风险报告查询与代理平台,支持个人信用查询、小微企业风控、贷前风险背调等多场景报告应用,免费开通代理权限,助力高效识别信用与风险。" />
|
<meta property="twitter:description" content="天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。" />
|
||||||
|
|
||||||
<!-- 其他重要meta标签 -->
|
<!-- 其他重要meta标签 -->
|
||||||
<meta name="theme-color" content="#3498db" />
|
<meta name="theme-color" content="#3498db" />
|
||||||
@@ -57,11 +57,11 @@
|
|||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "WebSite",
|
"@type": "WebSite",
|
||||||
"name": "天远数据",
|
"name": "天远数据",
|
||||||
"url": "https://www.zhinengcha.cn/",
|
"url": "https://www.tianyuandb.com/",
|
||||||
"description": "专业大数据风险报告查询与代理平台,支持个人信用查询、小微企业风控、贷前风险背调等多场景报告应用",
|
"description": "专业大数据风险报告查询与代理平台,支持个人信用查询、小微企业风控、贷前风险背调等多场景报告应用",
|
||||||
"potentialAction": {
|
"potentialAction": {
|
||||||
"@type": "SearchAction",
|
"@type": "SearchAction",
|
||||||
"target": "https://www.zhinengcha.cn/search?q={search_term_string}",
|
"target": "https://www.tianyuandb.com/search?q={search_term_string}",
|
||||||
"query-input": "required name=search_term_string"
|
"query-input": "required name=search_term_string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "Organization",
|
"@type": "Organization",
|
||||||
"name": "天远数据",
|
"name": "天远数据",
|
||||||
"url": "https://www.zhinengcha.cn/",
|
"url": "https://www.tianyuandb.com/",
|
||||||
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -84,9 +84,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- 预加载关键资源 -->
|
<!-- 预加载关键资源 -->
|
||||||
<link rel="preconnect" href="https://www.zhinengcha.cn">
|
<link rel="preconnect" href="https://www.tianyuandb.com">
|
||||||
<link rel="preconnect" href="https://res.wx.qq.com">
|
<link rel="preconnect" href="https://res.wx.qq.com">
|
||||||
<link rel="dns-prefetch" href="https://www.zhinengcha.cn">
|
<link rel="dns-prefetch" href="https://www.tianyuandb.com">
|
||||||
<link rel="dns-prefetch" href="https://res.wx.qq.com">
|
<link rel="dns-prefetch" href="https://res.wx.qq.com">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -181,6 +181,14 @@
|
|||||||
<div class="loading-text">加载中</div>
|
<div class="loading-text">加载中</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
<div id="captcha-element"></div>
|
||||||
|
<script>
|
||||||
|
window.AliyunCaptchaConfig = { region: "cn", prefix: "12zxnj" };
|
||||||
|
</script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js"
|
||||||
|
></script>
|
||||||
|
|
||||||
<script type="module" src="/src/main.js"></script>
|
<script type="module" src="/src/main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
BIN
public/logo.png
Normal file
BIN
public/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 428 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 124 KiB |
@@ -44,7 +44,7 @@ Disallow: /js/
|
|||||||
Disallow: /css/
|
Disallow: /css/
|
||||||
|
|
||||||
# 网站地图
|
# 网站地图
|
||||||
Sitemap: https://www.zhinengcha.cn/sitemap.xml
|
Sitemap: https://www.tianyuandb.com/sitemap.xml
|
||||||
|
|
||||||
# 爬取延迟(毫秒)
|
# 爬取延迟(毫秒)
|
||||||
Crawl-delay: 1
|
Crawl-delay: 1
|
||||||
|
|||||||
80
public/seo-templates/agent-invitation.html
Normal file
80
public/seo-templates/agent-invitation.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>邀请合作伙伴_发展代理享收益_推广返利计划_天远数据</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据推出合伙人邀请奖励机制。邀请好友注册成为合作伙伴,每单不仅可获得推广收益,还可叠加合作伙伴活跃奖励及定价差额收益。打造专属推广团队,实现收益持续增长。">
|
||||||
|
<meta name="keywords" content="渠道合作伙伴,商业收益管理,流量合规变现,业务推广系统,代理后台">
|
||||||
|
|
||||||
|
<meta property="og:title" content="邀请合作伙伴_发展代理享收益_推广返利计划_天远数据">
|
||||||
|
<meta property="og:description" content="天远数据推出合伙人邀请奖励机制。邀请好友注册成为合作伙伴,每单不仅可获得推广收益,还可叠加合作伙伴活跃奖励及定价差额收益。打造专属推广团队,实现收益持续增长。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/agent/invitation">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="邀请合作伙伴_发展代理享收益_推广返利计划_天远数据">
|
||||||
|
<meta name="twitter:description" content="天远数据推出合伙人邀请奖励机制。邀请好友注册成为合作伙伴,每单不仅可获得推广收益,还可叠加合作伙伴活跃奖励及定价差额收益。打造专属推广团队,实现收益持续增长。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/agent/invitation">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/agent/invitation">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "邀请合作伙伴_发展代理享收益_推广返利计划_天远数据",
|
||||||
|
"description": "天远数据推出合伙人邀请奖励机制。邀请好友注册成为合作伙伴,每单不仅可获得推广收益,还可叠加合作伙伴活跃奖励及定价差额收益。打造专属推广团队,实现收益持续增长。",
|
||||||
|
"url": "https://www.tianyuandb.com/agent/invitation",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>邀请合作伙伴_发展代理享收益_推广返利计划_天远数据</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/agent/invitation">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据推出合伙人邀请奖励机制。邀请好友注册成为合作伙伴,每单不仅可获得推广收益,还可叠加合作伙伴活跃奖励及定价差额收益。打造专属推广团队,实现收益持续增长。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/agent-promote.html
Normal file
80
public/seo-templates/agent-promote.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>生成推广码_自定义价格_0成本代理查价系统_天远数据</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据推广中心支持代理自主设置报告价格。在此选择报告类型,自定义客户查询价,0成本生成专属推广链接或二维码。差价即为利润,实现个人风险报告的私域流量变现。">
|
||||||
|
<meta name="keywords" content="推广码生成,自定义查价系统,代理收益工具,代理推广链接,流量变现平台,天远数据推广">
|
||||||
|
|
||||||
|
<meta property="og:title" content="生成推广码_自定义价格_0成本代理查价系统_天远数据">
|
||||||
|
<meta property="og:description" content="天远数据推广中心支持代理自主设置报告价格。在此选择报告类型,自定义客户查询价,0成本生成专属推广链接或二维码。差价即为利润,实现个人风险报告的私域流量变现。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/agent/promote">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="生成推广码_自定义价格_0成本代理查价系统_天远数据">
|
||||||
|
<meta name="twitter:description" content="天远数据推广中心支持代理自主设置报告价格。在此选择报告类型,自定义客户查询价,0成本生成专属推广链接或二维码。差价即为利润,实现个人风险报告的私域流量变现。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/agent/promote">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/agent/promote">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "生成推广码_自定义价格_0成本代理查价系统_天远数据",
|
||||||
|
"description": "天远数据推广中心支持代理自主设置报告价格。在此选择报告类型,自定义客户查询价,0成本生成专属推广链接或二维码。差价即为利润,实现个人风险报告的私域流量变现。",
|
||||||
|
"url": "https://www.tianyuandb.com/agent/promote",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>生成推广码_自定义价格_0成本代理查价系统_天远数据</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/agent/promote">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据推广中心支持代理自主设置报告价格。在此选择报告类型,自定义客户查询价,0成本生成专属推广链接或二维码。差价即为利润,实现个人风险报告的私域流量变现。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/agent.html
Normal file
80
public/seo-templates/agent.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>天远数据代理 - 免费开通代理权限 | 大数据风险报告代理</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据代理平台,免费开通代理权限,享受大数据风险报告查询服务代理收益。专业的大数据风险报告、婚姻查询、个人信用评估等服务的代理合作。">
|
||||||
|
<meta name="keywords" content="天远数据代理, 免费代理, 大数据风险报告代理, 代理权限, 代理收益">
|
||||||
|
|
||||||
|
<meta property="og:title" content="天远数据代理 - 免费开通代理权限 | 大数据风险报告代理">
|
||||||
|
<meta property="og:description" content="天远数据代理平台,免费开通代理权限,享受大数据风险报告查询服务代理收益。专业的大数据风险报告、婚姻查询、个人信用评估等服务的代理合作。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/agent">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="天远数据代理 - 免费开通代理权限 | 大数据风险报告代理">
|
||||||
|
<meta name="twitter:description" content="天远数据代理平台,免费开通代理权限,享受大数据风险报告查询服务代理收益。专业的大数据风险报告、婚姻查询、个人信用评估等服务的代理合作。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/agent">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/agent">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "天远数据代理 - 免费开通代理权限 | 大数据风险报告代理",
|
||||||
|
"description": "天远数据代理平台,免费开通代理权限,享受大数据风险报告查询服务代理收益。专业的大数据风险报告、婚姻查询、个人信用评估等服务的代理合作。",
|
||||||
|
"url": "https://www.tianyuandb.com/agent",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>天远数据代理 - 免费开通代理权限 | 大数据风险报告代理</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/agent">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据代理平台,免费开通代理权限,享受大数据风险报告查询服务代理收益。专业的大数据风险报告、婚姻查询、个人信用评估等服务的代理合作。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/example.html
Normal file
80
public/seo-templates/example.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>示例报告 - 天远数据报告展示 | 大数据风险报告样例</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据示例报告展示,包含大数据风险报告、婚姻状况查询、个人信用评估等服务的报告样例,让用户了解报告内容和格式。">
|
||||||
|
<meta name="keywords" content="示例报告, 报告展示, 报告样例, 大数据风险报告, 婚姻查询报告">
|
||||||
|
|
||||||
|
<meta property="og:title" content="示例报告 - 天远数据报告展示 | 大数据风险报告样例">
|
||||||
|
<meta property="og:description" content="天远数据示例报告展示,包含大数据风险报告、婚姻状况查询、个人信用评估等服务的报告样例,让用户了解报告内容和格式。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/example">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="示例报告 - 天远数据报告展示 | 大数据风险报告样例">
|
||||||
|
<meta name="twitter:description" content="天远数据示例报告展示,包含大数据风险报告、婚姻状况查询、个人信用评估等服务的报告样例,让用户了解报告内容和格式。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/example">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/example">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "示例报告 - 天远数据报告展示 | 大数据风险报告样例",
|
||||||
|
"description": "天远数据示例报告展示,包含大数据风险报告、婚姻状况查询、个人信用评估等服务的报告样例,让用户了解报告内容和格式。",
|
||||||
|
"url": "https://www.tianyuandb.com/example",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>示例报告 - 天远数据报告展示 | 大数据风险报告样例</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/example">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据示例报告展示,包含大数据风险报告、婚姻状况查询、个人信用评估等服务的报告样例,让用户了解报告内容和格式。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/help-guide.html
Normal file
80
public/seo-templates/help-guide.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>使用指南 - 天远数据操作教程 | 功能说明</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据详细使用指南,包含各功能模块的操作教程、功能说明、注意事项等,让用户快速上手使用。">
|
||||||
|
<meta name="keywords" content="使用指南, 操作教程, 功能说明, 快速上手, 天远数据教程">
|
||||||
|
|
||||||
|
<meta property="og:title" content="使用指南 - 天远数据操作教程 | 功能说明">
|
||||||
|
<meta property="og:description" content="天远数据详细使用指南,包含各功能模块的操作教程、功能说明、注意事项等,让用户快速上手使用。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/help/guide">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="使用指南 - 天远数据操作教程 | 功能说明">
|
||||||
|
<meta name="twitter:description" content="天远数据详细使用指南,包含各功能模块的操作教程、功能说明、注意事项等,让用户快速上手使用。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/help/guide">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/help/guide">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "使用指南 - 天远数据操作教程 | 功能说明",
|
||||||
|
"description": "天远数据详细使用指南,包含各功能模块的操作教程、功能说明、注意事项等,让用户快速上手使用。",
|
||||||
|
"url": "https://www.tianyuandb.com/help/guide",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>使用指南 - 天远数据操作教程 | 功能说明</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/help/guide">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据详细使用指南,包含各功能模块的操作教程、功能说明、注意事项等,让用户快速上手使用。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/help.html
Normal file
80
public/seo-templates/help.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>天远数据帮助中心_代理操作指南_推广收益计算常见问题</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据帮助中心提供全方位的代理操作指引。包含如何成为代理、推广报告生成教程、收益与成本计算规则及推广效率提升方案。">
|
||||||
|
<meta name="keywords" content="天远数据教程,代理新手指南,推广收益计算,报告推广">
|
||||||
|
|
||||||
|
<meta property="og:title" content="天远数据帮助中心_代理操作指南_推广收益计算常见问题">
|
||||||
|
<meta property="og:description" content="天远数据帮助中心提供全方位的代理操作指引。包含如何成为代理、推广报告生成教程、收益与成本计算规则及推广效率提升方案。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/help">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="天远数据帮助中心_代理操作指南_推广收益计算常见问题">
|
||||||
|
<meta name="twitter:description" content="天远数据帮助中心提供全方位的代理操作指引。包含如何成为代理、推广报告生成教程、收益与成本计算规则及推广效率提升方案。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/help">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/help">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "天远数据帮助中心_代理操作指南_推广收益计算常见问题",
|
||||||
|
"description": "天远数据帮助中心提供全方位的代理操作指引。包含如何成为代理、推广报告生成教程、收益与成本计算规则及推广效率提升方案。",
|
||||||
|
"url": "https://www.tianyuandb.com/help",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>天远数据帮助中心_代理操作指南_推广收益计算常见问题</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/help">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据帮助中心提供全方位的代理操作指引。包含如何成为代理、推广报告生成教程、收益与成本计算规则及推广效率提升方案。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/historyQuery.html
Normal file
80
public/seo-templates/historyQuery.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>我的报告_历史查询记录_天远数据</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据用户个人中心,查看及下载历史查询报告。">
|
||||||
|
<meta name="keywords" content="我的报告,历史记录,天远数据">
|
||||||
|
|
||||||
|
<meta property="og:title" content="我的报告_历史查询记录_天远数据">
|
||||||
|
<meta property="og:description" content="天远数据用户个人中心,查看及下载历史查询报告。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/historyQuery">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="我的报告_历史查询记录_天远数据">
|
||||||
|
<meta name="twitter:description" content="天远数据用户个人中心,查看及下载历史查询报告。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/historyQuery">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/historyQuery">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "我的报告_历史查询记录_天远数据",
|
||||||
|
"description": "天远数据用户个人中心,查看及下载历史查询报告。",
|
||||||
|
"url": "https://www.tianyuandb.com/historyQuery",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>我的报告_历史查询记录_天远数据</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/historyQuery">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据用户个人中心,查看及下载历史查询报告。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/index.html
Normal file
80
public/seo-templates/index.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。">
|
||||||
|
<meta name="keywords" content="天远数据,职场背调,风险核验报告,家政背景核验,第三方背调,企业风控服务,数据报告分销">
|
||||||
|
|
||||||
|
<meta property="og:title" content="天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台">
|
||||||
|
<meta property="og:description" content="天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台">
|
||||||
|
<meta name="twitter:description" content="天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台",
|
||||||
|
"description": "天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。",
|
||||||
|
"url": "https://www.tianyuandb.com",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/inquire-backgroundcheck.html
Normal file
80
public/seo-templates/inquire-backgroundcheck.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>入职背景核验_候选人履历核验_职场信用与竞业排查_天远数据</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据职场风险报告助力企业构建防御体系。基于司法级大数据,一键筛查候选人司法涉诉记录、学历信息、商业利益冲突、历史违约记录及不良社会风险。官方数据,客观预警入职风险,辅助HR高效决策。">
|
||||||
|
<meta name="keywords" content="入职风险评估,候选人背景核验,简历真伪辨别,竞业限制核验,职场信用报告,员工风险预警">
|
||||||
|
|
||||||
|
<meta property="og:title" content="入职背景核验_候选人履历核验_职场信用与竞业排查_天远数据">
|
||||||
|
<meta property="og:description" content="天远数据职场风险报告助力企业构建防御体系。基于司法级大数据,一键筛查候选人司法涉诉记录、学历信息、商业利益冲突、历史违约记录及不良社会风险。官方数据,客观预警入职风险,辅助HR高效决策。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/inquire/backgroundcheck">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="入职背景核验_候选人履历核验_职场信用与竞业排查_天远数据">
|
||||||
|
<meta name="twitter:description" content="天远数据职场风险报告助力企业构建防御体系。基于司法级大数据,一键筛查候选人司法涉诉记录、学历信息、商业利益冲突、历史违约记录及不良社会风险。官方数据,客观预警入职风险,辅助HR高效决策。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/inquire/backgroundcheck">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/inquire/backgroundcheck">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "入职背景核验_候选人履历核验_职场信用与竞业排查_天远数据",
|
||||||
|
"description": "天远数据职场风险报告助力企业构建防御体系。基于司法级大数据,一键筛查候选人司法涉诉记录、学历信息、商业利益冲突、历史违约记录及不良社会风险。官方数据,客观预警入职风险,辅助HR高效决策。",
|
||||||
|
"url": "https://www.tianyuandb.com/inquire/backgroundcheck",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>入职背景核验_候选人履历核验_职场信用与竞业排查_天远数据</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/inquire/backgroundcheck">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据职场风险报告助力企业构建防御体系。基于司法级大数据,一键筛查候选人司法涉诉记录、学历信息、商业利益冲突、历史违约记录及不良社会风险。官方数据,客观预警入职风险,辅助HR高效决策。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/inquire-companyinfo.html
Normal file
80
public/seo-templates/inquire-companyinfo.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>企业信用风险评估_工商经营异常与司法诉讼核查_天远数据</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据提供全维度的企业商业画像。基于官方公示数据,核验目标企业的工商变更、经营异常名录、行政处罚、投融资背景及关联风险。深度评估商业履约能力,透视合作方真实状况,规避合同陷阱。">
|
||||||
|
<meta name="keywords" content="企业信用画像,公司经营风险,工商异常名录,企业履约评估,商业背景核验">
|
||||||
|
|
||||||
|
<meta property="og:title" content="企业信用风险评估_工商经营异常与司法诉讼核查_天远数据">
|
||||||
|
<meta property="og:description" content="天远数据提供全维度的企业商业画像。基于官方公示数据,核验目标企业的工商变更、经营异常名录、行政处罚、投融资背景及关联风险。深度评估商业履约能力,透视合作方真实状况,规避合同陷阱。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/inquire/companyinfo">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="企业信用风险评估_工商经营异常与司法诉讼核查_天远数据">
|
||||||
|
<meta name="twitter:description" content="天远数据提供全维度的企业商业画像。基于官方公示数据,核验目标企业的工商变更、经营异常名录、行政处罚、投融资背景及关联风险。深度评估商业履约能力,透视合作方真实状况,规避合同陷阱。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/inquire/companyinfo">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/inquire/companyinfo">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "企业信用风险评估_工商经营异常与司法诉讼核查_天远数据",
|
||||||
|
"description": "天远数据提供全维度的企业商业画像。基于官方公示数据,核验目标企业的工商变更、经营异常名录、行政处罚、投融资背景及关联风险。深度评估商业履约能力,透视合作方真实状况,规避合同陷阱。",
|
||||||
|
"url": "https://www.tianyuandb.com/inquire/companyinfo",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>企业信用风险评估_工商经营异常与司法诉讼核查_天远数据</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/inquire/companyinfo">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据提供全维度的企业商业画像。基于官方公示数据,核验目标企业的工商变更、经营异常名录、行政处罚、投融资背景及关联风险。深度评估商业履约能力,透视合作方真实状况,规避合同陷阱。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/inquire-homeservice.html
Normal file
80
public/seo-templates/inquire-homeservice.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>家政人员背景核实_保姆月嫂司法风险筛查_用工安全评估_天远数据</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据家政风险报告,为家庭用人安全把关。通过合法大数据,快速筛查家政人员的司法诉讼、失信被执行记录及社会不良风险标签。有效识别潜在隐患,预防雇佣纠纷,让您找保姆、请月嫂更放心。">
|
||||||
|
<meta name="keywords" content="保姆背景核验,月嫂风险筛查,家政人员核验,育儿嫂背景核实,雇佣风险防范">
|
||||||
|
|
||||||
|
<meta property="og:title" content="家政人员背景核实_保姆月嫂司法风险筛查_用工安全评估_天远数据">
|
||||||
|
<meta property="og:description" content="天远数据家政风险报告,为家庭用人安全把关。通过合法大数据,快速筛查家政人员的司法诉讼、失信被执行记录及社会不良风险标签。有效识别潜在隐患,预防雇佣纠纷,让您找保姆、请月嫂更放心。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/inquire/homeservice">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="家政人员背景核实_保姆月嫂司法风险筛查_用工安全评估_天远数据">
|
||||||
|
<meta name="twitter:description" content="天远数据家政风险报告,为家庭用人安全把关。通过合法大数据,快速筛查家政人员的司法诉讼、失信被执行记录及社会不良风险标签。有效识别潜在隐患,预防雇佣纠纷,让您找保姆、请月嫂更放心。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/inquire/homeservice">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/inquire/homeservice">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "家政人员背景核实_保姆月嫂司法风险筛查_用工安全评估_天远数据",
|
||||||
|
"description": "天远数据家政风险报告,为家庭用人安全把关。通过合法大数据,快速筛查家政人员的司法诉讼、失信被执行记录及社会不良风险标签。有效识别潜在隐患,预防雇佣纠纷,让您找保姆、请月嫂更放心。",
|
||||||
|
"url": "https://www.tianyuandb.com/inquire/homeservice",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>家政人员背景核实_保姆月嫂司法风险筛查_用工安全评估_天远数据</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/inquire/homeservice">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据家政风险报告,为家庭用人安全把关。通过合法大数据,快速筛查家政人员的司法诉讼、失信被执行记录及社会不良风险标签。有效识别潜在隐患,预防雇佣纠纷,让您找保姆、请月嫂更放心。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/inquire-marriage.html
Normal file
80
public/seo-templates/inquire-marriage.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>婚恋对象背景了解_司法诉讼与不良记录筛查_婚前风险评估_天远数据</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据提供专业的婚恋风险评估工具。基于合法的公开司法数据,深度排查法律诉讼记录、失信被执行信息及潜在的履约风险。数据来源合规,仅供个人防范参考,拒绝隐私泄露,为幸福保驾护航。">
|
||||||
|
<meta name="keywords" content="婚恋背景核验,婚前风险了解,司法记录核验,个人履约风险,背景核实">
|
||||||
|
|
||||||
|
<meta property="og:title" content="婚恋对象背景了解_司法诉讼与不良记录筛查_婚前风险评估_天远数据">
|
||||||
|
<meta property="og:description" content="天远数据提供专业的婚恋风险评估工具。基于合法的公开司法数据,深度排查法律诉讼记录、失信被执行信息及潜在的履约风险。数据来源合规,仅供个人防范参考,拒绝隐私泄露,为幸福保驾护航。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/inquire/marriage">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="婚恋对象背景了解_司法诉讼与不良记录筛查_婚前风险评估_天远数据">
|
||||||
|
<meta name="twitter:description" content="天远数据提供专业的婚恋风险评估工具。基于合法的公开司法数据,深度排查法律诉讼记录、失信被执行信息及潜在的履约风险。数据来源合规,仅供个人防范参考,拒绝隐私泄露,为幸福保驾护航。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/inquire/marriage">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/inquire/marriage">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "婚恋对象背景了解_司法诉讼与不良记录筛查_婚前风险评估_天远数据",
|
||||||
|
"description": "天远数据提供专业的婚恋风险评估工具。基于合法的公开司法数据,深度排查法律诉讼记录、失信被执行信息及潜在的履约风险。数据来源合规,仅供个人防范参考,拒绝隐私泄露,为幸福保驾护航。",
|
||||||
|
"url": "https://www.tianyuandb.com/inquire/marriage",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>婚恋对象背景了解_司法诉讼与不良记录筛查_婚前风险评估_天远数据</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/inquire/marriage">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据提供专业的婚恋风险评估工具。基于合法的公开司法数据,深度排查法律诉讼记录、失信被执行信息及潜在的履约风险。数据来源合规,仅供个人防范参考,拒绝隐私泄露,为幸福保驾护航。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/inquire-personalData.html
Normal file
80
public/seo-templates/inquire-personalData.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>个人综合风险报告_个人履约评分_多维数据检测_天远数据</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据提供个人全维信用画像扫描。一键检测司法涉诉记录、历史履约情况、号码状态异常检测及个人消费等级。数据同步权威行业系统,采用银行级加密技术,保障信息安全,助您全面了解自身信用状况。">
|
||||||
|
<meta name="keywords" content="个人风险评估,信用状况评估,综合履约能力,司法风险自查,风险标签检测">
|
||||||
|
|
||||||
|
<meta property="og:title" content="个人综合风险报告_个人履约评分_多维数据检测_天远数据">
|
||||||
|
<meta property="og:description" content="天远数据提供个人全维信用画像扫描。一键检测司法涉诉记录、历史履约情况、号码状态异常检测及个人消费等级。数据同步权威行业系统,采用银行级加密技术,保障信息安全,助您全面了解自身信用状况。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/inquire/personalData">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="个人综合风险报告_个人履约评分_多维数据检测_天远数据">
|
||||||
|
<meta name="twitter:description" content="天远数据提供个人全维信用画像扫描。一键检测司法涉诉记录、历史履约情况、号码状态异常检测及个人消费等级。数据同步权威行业系统,采用银行级加密技术,保障信息安全,助您全面了解自身信用状况。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/inquire/personalData">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/inquire/personalData">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "个人综合风险报告_个人履约评分_多维数据检测_天远数据",
|
||||||
|
"description": "天远数据提供个人全维信用画像扫描。一键检测司法涉诉记录、历史履约情况、号码状态异常检测及个人消费等级。数据同步权威行业系统,采用银行级加密技术,保障信息安全,助您全面了解自身信用状况。",
|
||||||
|
"url": "https://www.tianyuandb.com/inquire/personalData",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>个人综合风险报告_个人履约评分_多维数据检测_天远数据</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/inquire/personalData">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据提供个人全维信用画像扫描。一键检测司法涉诉记录、历史履约情况、号码状态异常检测及个人消费等级。数据同步权威行业系统,采用银行级加密技术,保障信息安全,助您全面了解自身信用状况。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/inquire-preloanbackgroundcheck.html
Normal file
80
public/seo-templates/inquire-preloanbackgroundcheck.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>综合履约评分检测_多平台履约记录分析_个人财务履约报告_天远数据</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据提供专业的个人履约健康度体检服务。基于多维大数据分析,检测您的综合评分波动、历史履约记录及潜在的风险标签。本服务旨在帮助用户优化个人数据画像,提升信用管理意识,不提供任何信贷金融服务。">
|
||||||
|
<meta name="keywords" content="综合评分检测,多重履约压力分析,履约能力评估,综合评分优化,个人数据画像">
|
||||||
|
|
||||||
|
<meta property="og:title" content="综合履约评分检测_多平台履约记录分析_个人财务履约报告_天远数据">
|
||||||
|
<meta property="og:description" content="天远数据提供专业的个人履约健康度体检服务。基于多维大数据分析,检测您的综合评分波动、历史履约记录及潜在的风险标签。本服务旨在帮助用户优化个人数据画像,提升信用管理意识,不提供任何信贷金融服务。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/inquire/preloanbackgroundcheck">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="综合履约评分检测_多平台履约记录分析_个人财务履约报告_天远数据">
|
||||||
|
<meta name="twitter:description" content="天远数据提供专业的个人履约健康度体检服务。基于多维大数据分析,检测您的综合评分波动、历史履约记录及潜在的风险标签。本服务旨在帮助用户优化个人数据画像,提升信用管理意识,不提供任何信贷金融服务。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/inquire/preloanbackgroundcheck">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/inquire/preloanbackgroundcheck">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "综合履约评分检测_多平台履约记录分析_个人财务履约报告_天远数据",
|
||||||
|
"description": "天远数据提供专业的个人履约健康度体检服务。基于多维大数据分析,检测您的综合评分波动、历史履约记录及潜在的风险标签。本服务旨在帮助用户优化个人数据画像,提升信用管理意识,不提供任何信贷金融服务。",
|
||||||
|
"url": "https://www.tianyuandb.com/inquire/preloanbackgroundcheck",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>综合履约评分检测_多平台履约记录分析_个人财务履约报告_天远数据</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/inquire/preloanbackgroundcheck">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据提供专业的个人履约健康度体检服务。基于多维大数据分析,检测您的综合评分波动、历史履约记录及潜在的风险标签。本服务旨在帮助用户优化个人数据画像,提升信用管理意识,不提供任何信贷金融服务。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
public/seo-templates/service.html
Normal file
80
public/seo-templates/service.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>客服中心 - 天远数据在线客服 | 技术支持</title>
|
||||||
|
|
||||||
|
<meta name="description" content="天远数据客服中心,提供在线客服支持、技术咨询、问题反馈等服务,确保用户获得及时有效的帮助。">
|
||||||
|
<meta name="keywords" content="客服中心, 在线客服, 技术支持, 问题反馈, 天远数据客服">
|
||||||
|
|
||||||
|
<meta property="og:title" content="客服中心 - 天远数据在线客服 | 技术支持">
|
||||||
|
<meta property="og:description" content="天远数据客服中心,提供在线客服支持、技术咨询、问题反馈等服务,确保用户获得及时有效的帮助。">
|
||||||
|
<meta property="og:url" content="https://www.tianyuandb.com/service">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="客服中心 - 天远数据在线客服 | 技术支持">
|
||||||
|
<meta name="twitter:description" content="天远数据客服中心,提供在线客服支持、技术咨询、问题反馈等服务,确保用户获得及时有效的帮助。">
|
||||||
|
<meta name="twitter:url" content="https://www.tianyuandb.com/service">
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://www.tianyuandb.com/service">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebPage",
|
||||||
|
"name": "客服中心 - 天远数据在线客服 | 技术支持",
|
||||||
|
"description": "天远数据客服中心,提供在线客服支持、技术咨询、问题反馈等服务,确保用户获得及时有效的帮助。",
|
||||||
|
"url": "https://www.tianyuandb.com/service",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "天远数据",
|
||||||
|
"url": "https://www.tianyuandb.com/",
|
||||||
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>客服中心 - 天远数据在线客服 | 技术支持</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="https://www.tianyuandb.com/service">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>天远数据客服中心,提供在线客服支持、技术咨询、问题反馈等服务,确保用户获得及时有效的帮助。</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "天远数据|大数据风险报告查询与代理平台,支持个人和企业多场景风控应用",
|
"name": "天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台",
|
||||||
"short_name": "天远数据",
|
"short_name": "天远数据",
|
||||||
"description": "专业大数据风险报告查询与代理平台,支持个人信用查询、小微企业风控、贷前风险背调等多场景报告应用",
|
"description": "专业大数据风险报告查询与代理平台,支持个人信用查询、小微企业风控、贷前风险背调等多场景报告应用",
|
||||||
"start_url": "/",
|
"start_url": "/",
|
||||||
|
|||||||
@@ -1,67 +1,67 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/</loc>
|
<loc>https://www.tianyuandb.com/</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>daily</changefreq>
|
<changefreq>daily</changefreq>
|
||||||
<priority>1.0</priority>
|
<priority>1.0</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/agent</loc>
|
<loc>https://www.tianyuandb.com/agent</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>weekly</changefreq>
|
<changefreq>weekly</changefreq>
|
||||||
<priority>0.8</priority>
|
<priority>0.8</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/help</loc>
|
<loc>https://www.tianyuandb.com/help</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.7</priority>
|
<priority>0.7</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/help/guide</loc>
|
<loc>https://www.tianyuandb.com/help/guide</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/example</loc>
|
<loc>https://www.tianyuandb.com/example</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.6</priority>
|
<priority>0.6</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/service</loc>
|
<loc>https://www.tianyuandb.com/service</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.5</priority>
|
<priority>0.5</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/privacyPolicy</loc>
|
<loc>https://www.tianyuandb.com/privacyPolicy</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>yearly</changefreq>
|
<changefreq>yearly</changefreq>
|
||||||
<priority>0.3</priority>
|
<priority>0.3</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/userAgreement</loc>
|
<loc>https://www.tianyuandb.com/userAgreement</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>yearly</changefreq>
|
<changefreq>yearly</changefreq>
|
||||||
<priority>0.3</priority>
|
<priority>0.3</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/agentManageAgreement</loc>
|
<loc>https://www.tianyuandb.com/agentManageAgreement</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>yearly</changefreq>
|
<changefreq>yearly</changefreq>
|
||||||
<priority>0.3</priority>
|
<priority>0.3</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/agentSerivceAgreement</loc>
|
<loc>https://www.tianyuandb.com/agentSerivceAgreement</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>yearly</changefreq>
|
<changefreq>yearly</changefreq>
|
||||||
<priority>0.3</priority>
|
<priority>0.3</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://www.zhinengcha.cn/authorization</loc>
|
<loc>https://www.tianyuandb.com/authorization</loc>
|
||||||
<lastmod>2025-08-01</lastmod>
|
<lastmod>2025-08-01</lastmod>
|
||||||
<changefreq>yearly</changefreq>
|
<changefreq>yearly</changefreq>
|
||||||
<priority>0.3</priority>
|
<priority>0.3</priority>
|
||||||
|
|||||||
@@ -592,7 +592,7 @@ watch([reportData, componentRiskScores], () => {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a class="text-blue-500" href="https://beian.miit.gov.cn">
|
<a class="text-blue-500" href="https://beian.miit.gov.cn">
|
||||||
琼ICP备2024048057号-2
|
琼ICP备2024038584号-13
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
404
report-viewer/src/ui/FLXG7E8F/components/CaseDetail.vue
Normal file
404
report-viewer/src/ui/FLXG7E8F/components/CaseDetail.vue
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
<template>
|
||||||
|
<div class="px-4 pb-4">
|
||||||
|
<div class="grid grid-cols-[max-content_1fr] gap-x-2 gap-y-3">
|
||||||
|
<!-- 经办法院/执行法院 -->
|
||||||
|
<span class="text-base text-[#666666]">{{ isSpecialCase ? '执行法院' : '经办法院' }}:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jbfy || caseData.executiveCourt || "—" }}</span>
|
||||||
|
|
||||||
|
<!-- 所属地域 -->
|
||||||
|
<span class="text-base text-[#666666]">所属地域:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_ssdy || caseData.province || "—" }}</span>
|
||||||
|
|
||||||
|
<!-- 案件类型 -->
|
||||||
|
<template v-if="caseData.n_ajlx">
|
||||||
|
<span class="text-base text-[#666666]">案件类型:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_ajlx || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 案号 -->
|
||||||
|
<template v-if="caseData.c_ah">
|
||||||
|
<span class="text-base text-[#666666]">案号:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_ah || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 原审案号 -->
|
||||||
|
<template v-if="caseData.c_ah_ys">
|
||||||
|
<span class="text-base text-[#666666]">原审案号:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_ah_ys || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 后续案号 -->
|
||||||
|
<template v-if="caseData.c_ah_hx">
|
||||||
|
<span class="text-base text-[#666666]">后续案号:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_ah_hx || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 立案时间 -->
|
||||||
|
<template v-if="caseData.d_larq || caseData.fileDate || caseData.larq">
|
||||||
|
<span class="text-base text-[#666666]">立案时间:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.d_larq || caseData.fileDate || caseData.larq) }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 立案案由 -->
|
||||||
|
<template v-if="caseData.n_laay_tree || caseData.n_laay">
|
||||||
|
<span class="text-base text-[#666666]">立案案由:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_laay_tree || caseData.n_laay || "暂无" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 立案案由标签 -->
|
||||||
|
<template v-if="caseData.n_laay_tag">
|
||||||
|
<span class="text-base text-[#666666]">立案案由标签:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_laay_tag || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 当事人信息 -->
|
||||||
|
<template v-if="caseData.c_dsrxx && caseData.c_dsrxx.length > 0">
|
||||||
|
<span class="text-base text-[#666666]">当事人信息:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">
|
||||||
|
<span v-for="(party, partyIndex) in caseData.c_dsrxx" :key="partyIndex">
|
||||||
|
{{ party.n_ssdw || "其他" }}: {{ party.c_mc }}<span v-if="partyIndex < caseData.c_dsrxx.length - 1">; </span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 失信被执行人特有字段 -->
|
||||||
|
<template v-if="caseType === 'breachCase'">
|
||||||
|
<!-- 案号 -->
|
||||||
|
<template v-if="caseData.caseNumber">
|
||||||
|
<span class="text-base text-[#666666]">案号:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.caseNumber || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 发布日期 -->
|
||||||
|
<template v-if="caseData.issueDate">
|
||||||
|
<span class="text-base text-[#666666]">发布日期:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.issueDate) }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 性别 -->
|
||||||
|
<template v-if="caseData.sex">
|
||||||
|
<span class="text-base text-[#666666]">性别:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.sex || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 履行情况 -->
|
||||||
|
<template v-if="caseData.fulfillStatus">
|
||||||
|
<span class="text-base text-[#666666]">履行情况:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.fulfillStatus || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 判决金额估计 -->
|
||||||
|
<template v-if="caseData.estimatedJudgementAmount">
|
||||||
|
<span class="text-base text-[#666666]">判决金额估计:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.estimatedJudgementAmount) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 失信被执行人行为具体情形 -->
|
||||||
|
<template v-if="caseData.concreteDetails">
|
||||||
|
<span class="text-base text-[#666666]">行为具体情形:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.concreteDetails || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 生效法律文书确定的义务 -->
|
||||||
|
<template v-if="caseData.obligation">
|
||||||
|
<span class="text-base text-[#666666]">生效法律文书确定的义务:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.obligation || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 执行依据单位 -->
|
||||||
|
<template v-if="caseData.enforcementBasisOrganization">
|
||||||
|
<span class="text-base text-[#666666]">执行依据单位:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.enforcementBasisOrganization || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 执行依据文号 -->
|
||||||
|
<template v-if="caseData.enforcementBasisNumber">
|
||||||
|
<span class="text-base text-[#666666]">执行依据文号:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.enforcementBasisNumber || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 限制消费被执行人特有字段 -->
|
||||||
|
<template v-if="caseType === 'consumptionRestriction'">
|
||||||
|
<!-- 案件编号 -->
|
||||||
|
<template v-if="caseData.caseNumber">
|
||||||
|
<span class="text-base text-[#666666]">案件编号:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.caseNumber || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 发布日期 -->
|
||||||
|
<template v-if="caseData.issueDate">
|
||||||
|
<span class="text-base text-[#666666]">发布日期:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.issueDate) }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 立案时间 -->
|
||||||
|
<template v-if="caseData.fileDate">
|
||||||
|
<span class="text-base text-[#666666]">立案时间:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.fileDate) }}</span>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 刑事案件特有字段 -->
|
||||||
|
<template v-if="caseType === 'criminal'">
|
||||||
|
<!-- 定罪罪名 -->
|
||||||
|
<template v-if="caseData.n_dzzm">
|
||||||
|
<span class="text-base text-[#666666]">定罪罪名:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_dzzm || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 定罪罪名详细 -->
|
||||||
|
<template v-if="caseData.n_dzzm_tree">
|
||||||
|
<span class="text-base text-[#666666]">定罪罪名详细:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_dzzm_tree || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 判处结果 -->
|
||||||
|
<template v-if="caseData.n_pcjg">
|
||||||
|
<span class="text-base text-[#666666]">判处结果:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_pcjg || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 犯罪金额 -->
|
||||||
|
<template v-if="caseData.n_fzje">
|
||||||
|
<span class="text-base text-[#666666]">犯罪金额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_fzje) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 被请求赔偿金额 -->
|
||||||
|
<template v-if="caseData.n_bqqpcje">
|
||||||
|
<span class="text-base text-[#666666]">被请求赔偿金额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_bqqpcje) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 财产刑执行金额 -->
|
||||||
|
<template v-if="caseData.n_ccxzxje">
|
||||||
|
<span class="text-base text-[#666666]">财产刑执行金额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_ccxzxje) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 财产刑执行金额估计 -->
|
||||||
|
<template v-if="caseData.n_ccxzxje_gj">
|
||||||
|
<span class="text-base text-[#666666]">财产刑执行金额估计:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_ccxzxje_gj) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 判处赔偿金额 -->
|
||||||
|
<template v-if="caseData.n_pcpcje">
|
||||||
|
<span class="text-base text-[#666666]">判处赔偿金额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_pcpcje) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 判处赔偿金额估计 -->
|
||||||
|
<template v-if="caseData.n_pcpcje_gj">
|
||||||
|
<span class="text-base text-[#666666]">判处赔偿金额估计:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_pcpcje_gj) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 被请求赔偿金额估计 -->
|
||||||
|
<template v-if="caseData.n_bqqpcje_gj">
|
||||||
|
<span class="text-base text-[#666666]">被请求赔偿金额估计:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_bqqpcje_gj) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 执行案件特有字段 -->
|
||||||
|
<template v-if="caseType === 'implement'">
|
||||||
|
<!-- 申请执行标的金额 -->
|
||||||
|
<template v-if="caseData.n_sqzxbdje">
|
||||||
|
<span class="text-base text-[#666666]">申请执行标的金额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_sqzxbdje) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 实际到位金额 -->
|
||||||
|
<template v-if="caseData.n_sjdwje !== undefined">
|
||||||
|
<span class="text-base text-[#666666]">实际到位金额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_sjdwje) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 未执行金额 -->
|
||||||
|
<template v-if="caseData.n_wzxje !== undefined">
|
||||||
|
<span class="text-base text-[#666666]">未执行金额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_wzxje) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 相关案件号 -->
|
||||||
|
<template v-if="caseData.c_gkws_glah">
|
||||||
|
<span class="text-base text-[#666666]">相关案件号:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_gkws_glah || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 非诉保全审查案件特有字段 -->
|
||||||
|
<template v-if="caseType === 'preservation'">
|
||||||
|
<!-- 申请保全数额 -->
|
||||||
|
<template v-if="caseData.n_sqbqse">
|
||||||
|
<span class="text-base text-[#666666]">申请保全数额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_sqbqse) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 申请保全标的物 -->
|
||||||
|
<template v-if="caseData.c_sqbqbdw">
|
||||||
|
<span class="text-base text-[#666666]">申请保全标的物:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_sqbqbdw || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 案件通用字段 -->
|
||||||
|
<!-- 诉讼地位 -->
|
||||||
|
<template v-if="caseData.n_ssdw">
|
||||||
|
<span class="text-base text-[#666666]">诉讼地位:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_ssdw || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 一审诉讼地位 -->
|
||||||
|
<template v-if="caseData.n_ssdw_ys">
|
||||||
|
<span class="text-base text-[#666666]">一审诉讼地位:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_ssdw_ys || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 案件进展阶段 -->
|
||||||
|
<template v-if="caseData.n_ajjzjd">
|
||||||
|
<span class="text-base text-[#666666]">案件进展阶段:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_ajjzjd || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 审理程序 -->
|
||||||
|
<template v-if="caseData.n_slcx">
|
||||||
|
<span class="text-base text-[#666666]">审理程序:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_slcx || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 法院所属层级 -->
|
||||||
|
<template v-if="caseData.n_jbfy_cj">
|
||||||
|
<span class="text-base text-[#666666]">法院所属层级:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jbfy_cj || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 起诉标的金额 -->
|
||||||
|
<template v-if="caseData.n_qsbdje">
|
||||||
|
<span class="text-base text-[#666666]">起诉标的金额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_qsbdje) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 起诉标的金额估计 -->
|
||||||
|
<template v-if="caseData.n_qsbdje_gj">
|
||||||
|
<span class="text-base text-[#666666]">起诉标的金额估计:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_qsbdje_gj) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 结案标的金额 -->
|
||||||
|
<template v-if="caseData.n_jabdje">
|
||||||
|
<span class="text-base text-[#666666]">结案标的金额:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_jabdje) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 结案标的金额估计 -->
|
||||||
|
<template v-if="caseData.n_jabdje_gj">
|
||||||
|
<span class="text-base text-[#666666]">结案标的金额估计:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatLawsuitMoney(caseData.n_jabdje_gj) || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 结案案由 -->
|
||||||
|
<template v-if="caseData.n_jaay_tree || caseData.n_jaay">
|
||||||
|
<span class="text-base text-[#666666]">结案案由:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jaay_tree || caseData.n_jaay || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 结案案由标签 -->
|
||||||
|
<template v-if="caseData.n_jaay_tag">
|
||||||
|
<span class="text-base text-[#666666]">结案案由标签:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jaay_tag || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 结案方式 -->
|
||||||
|
<template v-if="caseData.n_jafs">
|
||||||
|
<span class="text-base text-[#666666]">结案方式:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_jafs || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 结案时间 -->
|
||||||
|
<template v-if="caseData.d_jarq">
|
||||||
|
<span class="text-base text-[#666666]">结案时间:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ formatDate(caseData.d_jarq) }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 胜诉估计 -->
|
||||||
|
<template v-if="caseData.n_pj_victory">
|
||||||
|
<span class="text-base text-[#666666]">胜诉估计:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.n_pj_victory || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 公开文书ID -->
|
||||||
|
<template v-if="caseData.c_gkws_id">
|
||||||
|
<span class="text-base text-[#666666]">公开文书ID:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_gkws_id || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 相关当事人 -->
|
||||||
|
<template v-if="caseData.c_gkws_dsr">
|
||||||
|
<span class="text-base text-[#666666]">相关当事人:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_gkws_dsr || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 判决结果 -->
|
||||||
|
<template v-if="caseData.c_gkws_pjjg">
|
||||||
|
<span class="text-base text-[#666666]">判决结果:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_gkws_pjjg || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 审理方式信息 -->
|
||||||
|
<template v-if="caseData.c_slfsxx">
|
||||||
|
<span class="text-base text-[#666666]">审理方式信息:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">{{ caseData.c_slfsxx || "—" }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 后续案件信息 -->
|
||||||
|
<template v-if="caseData.next">
|
||||||
|
<span class="text-base text-[#666666]">后续案件:</span>
|
||||||
|
<span class="text-base font-medium text-[#333333]">
|
||||||
|
{{ caseData.next.c_ah }}
|
||||||
|
<span v-if="caseData.next.stage_type" class="ml-2 text-sm px-2 py-0.5 rounded bg-[#EB3C3C1A] text-[#EB3C3C]">
|
||||||
|
{{
|
||||||
|
caseData.next.stage_type === 2
|
||||||
|
? "二审"
|
||||||
|
: caseData.next.stage_type === 3
|
||||||
|
? "再审"
|
||||||
|
: caseData.next.stage_type === 4
|
||||||
|
? "申请再审"
|
||||||
|
: caseData.next.stage_type === 5
|
||||||
|
? "执行"
|
||||||
|
: "其他"
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { formatDate, formatLawsuitMoney } from '../utils/lawsuitUtils.js'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
caseData: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
typeColor: {
|
||||||
|
type: String,
|
||||||
|
default: 'text-blue-600 bg-blue-50'
|
||||||
|
},
|
||||||
|
caseType: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 判断是否为特殊案件类型(失信被执行人、限高被执行人)
|
||||||
|
const isSpecialCase = computed(() => {
|
||||||
|
return props.caseType === 'breachCase' || props.caseType === 'consumptionRestriction'
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
285
report-viewer/src/ui/FLXG7E8F/components/StatisticsOverview.vue
Normal file
285
report-viewer/src/ui/FLXG7E8F/components/StatisticsOverview.vue
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
<template>
|
||||||
|
<div class="">
|
||||||
|
<!-- 概览标题 -->
|
||||||
|
<div class="p-4">
|
||||||
|
<!-- 添加风险概览总结 -->
|
||||||
|
<div class="p-4 rounded-lg" :class="getRiskOverviewClass()">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="w-12 h-12 mr-3 flex-shrink-0">
|
||||||
|
<img :src="getRiskIcon()" alt="风险" class="w-12 h-12 object-contain" />
|
||||||
|
</div>
|
||||||
|
<div class=" text-gray-700">
|
||||||
|
{{ totalCases }}
|
||||||
|
起涉诉案件中,
|
||||||
|
<span v-if="stats.highRiskItems > 0" class="text-orange-600 font-medium">
|
||||||
|
{{ stats.highRiskItems }}
|
||||||
|
</span>
|
||||||
|
<span v-else class="text-green-600 font-medium">0</span>
|
||||||
|
起高风险案件
|
||||||
|
<span v-if="stats.caseTypes.length > 0" class="ml-1">
|
||||||
|
,涉及 {{ stats.caseTypes.length }} 种案件类型
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 主要风险指标 -->
|
||||||
|
<div class="grid grid-cols-2 gap-3 p-4">
|
||||||
|
<!-- 风险事项卡片 -->
|
||||||
|
<div class="p-4 bg-[#EB3C3C1A] border border-[#EB3C3C4D] rounded-xl text-center">
|
||||||
|
<div class="text-2xl font-bold text-[#EB3C3C] mb-1">{{ stats.totalRiskItems || 0 }}项</div>
|
||||||
|
<div class="text-sm font-medium text-gray-800 mb-1">风险事项</div>
|
||||||
|
<div class="text-sm text-gray-500">
|
||||||
|
平均{{ stats.totalRiskItems && totalCases > 0 ?
|
||||||
|
(stats.totalRiskItems / totalCases).toFixed(1) :
|
||||||
|
'0.0'
|
||||||
|
}}项/案件
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 高风险案件卡片 -->
|
||||||
|
<div class="p-4 bg-[#EB3C3C1A] border border-[#EB3C3C4D] rounded-xl text-center">
|
||||||
|
<div class="text-2xl font-bold text-[#EB3C3C] mb-1">{{ stats.highRiskItems || 0 }}家</div>
|
||||||
|
<div class="text-sm font-medium text-gray-800 mb-1">高风险案件</div>
|
||||||
|
<div class="text-sm text-gray-500 mb-1">
|
||||||
|
占比{{ totalCases > 0 && stats ?
|
||||||
|
((stats.highRiskItems /
|
||||||
|
totalCases) * 100).toFixed(1) : '0.0' }}%
|
||||||
|
</div>
|
||||||
|
<div class="text-sm text-orange-600">
|
||||||
|
<span class="mr-3">失信{{ stats.breachCaseCount || 0 }}</span>
|
||||||
|
<span style="color: #D6943E;">限高{{ stats.consumptionRestrictionCount || 0 }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 已结案件卡片 -->
|
||||||
|
<div class="p-4 bg-[#2B79EE1A] border border-[#2B79EE4D] rounded-xl text-center">
|
||||||
|
<div class="text-2xl font-bold text-[#2B79EE] mb-1">{{ stats.closedCases || 0 }}家</div>
|
||||||
|
<div class="text-sm font-medium text-gray-800 mb-1">已结案件</div>
|
||||||
|
<div class="text-sm text-gray-500">
|
||||||
|
占比{{ totalCases > 0 && stats ?
|
||||||
|
Math.round((stats.closedCases / totalCases) * 100) :
|
||||||
|
0
|
||||||
|
}}%
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 案件类型卡片 -->
|
||||||
|
<div class="p-4 bg-[#2B79EE1A] border border-[#2B79EE4D] rounded-xl text-center">
|
||||||
|
<div class="text-2xl font-bold text-[#2B79EE] mb-1">{{ stats.caseTypes.length || 0 }}家</div>
|
||||||
|
<div class="text-sm font-medium text-gray-800 mb-1">案件类型</div>
|
||||||
|
<div class="text-sm text-gray-500">
|
||||||
|
涉及多种类型
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
|
||||||
|
<!-- 案件类型分布 -->
|
||||||
|
<LTitle title="案件类型分布" />
|
||||||
|
<div class="h-[300px] px-4">
|
||||||
|
<v-chart :option="caseTypeChartOption" autoresize />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 风险等级分布 -->
|
||||||
|
<LTitle title="风险等级分布" />
|
||||||
|
<div class="bg-[#F9ECEC] border border-[#F0CACA] rounded-xl mx-4 p-4">
|
||||||
|
<div class="grid grid-cols-3 gap-4 text-center">
|
||||||
|
<!-- 高风险案件 -->
|
||||||
|
<div>
|
||||||
|
<div class="text-sm text-gray-600 mb-1">高风险案件</div>
|
||||||
|
<div class="text-xl font-bold text-[#EB3C3C]">{{ stats.highRiskItems || 0 }}条</div>
|
||||||
|
</div>
|
||||||
|
<!-- 中风险案件 -->
|
||||||
|
<div>
|
||||||
|
<div class="text-sm text-gray-600 mb-1">中风险案件</div>
|
||||||
|
<div class="text-xl font-bold text-[#EB3C3C]">{{ stats.mediumRiskItems || 0 }}条</div>
|
||||||
|
</div>
|
||||||
|
<!-- 低风险案件 -->
|
||||||
|
<div>
|
||||||
|
<div class="text-sm text-gray-600 mb-1">低风险案件</div>
|
||||||
|
<div class="text-xl font-bold text-[#D6943E]">{{ stats.lowRiskItems || 0 }}条</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { use } from 'echarts/core'
|
||||||
|
import { CanvasRenderer } from 'echarts/renderers'
|
||||||
|
import { BarChart } from 'echarts/charts'
|
||||||
|
import { GridComponent, TooltipComponent, TitleComponent, LegendComponent } from 'echarts/components'
|
||||||
|
import VChart from 'vue-echarts'
|
||||||
|
import LTitle from '@/components/LTitle.vue'
|
||||||
|
import { lawsuitTypeMap, getCaseTypeText, getCaseTypeDarkColor } from '../utils/lawsuitUtils.js'
|
||||||
|
|
||||||
|
// 注册必须的组件
|
||||||
|
use([CanvasRenderer, BarChart, GridComponent, TooltipComponent, TitleComponent, LegendComponent])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
stats: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
totalCases: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// 案件类型分布横向柱状图配置
|
||||||
|
const caseTypeChartOption = computed(() => {
|
||||||
|
// 获取所有可能的案件类型,确保即使没有数据的类型也会显示
|
||||||
|
const allCaseTypes = Object.keys(lawsuitTypeMap).map(key => ({
|
||||||
|
type: key,
|
||||||
|
name: lawsuitTypeMap[key].text,
|
||||||
|
color: lawsuitTypeMap[key].color,
|
||||||
|
darkColor: lawsuitTypeMap[key].darkColor,
|
||||||
|
count: 0, // 默认为0
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 如果有统计数据,更新数量
|
||||||
|
if (props.stats && props.stats.caseTypes && props.stats.caseTypes.length > 0) {
|
||||||
|
// 用实际数据更新默认值
|
||||||
|
props.stats.caseTypes.forEach(item => {
|
||||||
|
const existingType = allCaseTypes.find(type => type.type === item.type)
|
||||||
|
if (existingType) {
|
||||||
|
existingType.count = item.count
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 如果没有任何数据,显示暂无数据的信息
|
||||||
|
return {
|
||||||
|
title: {
|
||||||
|
text: '暂无数据',
|
||||||
|
left: 'center',
|
||||||
|
top: 'center',
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: 'normal',
|
||||||
|
color: '#aaa',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备横向柱状图数据 - 不过滤,显示所有类型
|
||||||
|
const categories = allCaseTypes.map(item => item.name)
|
||||||
|
const values = allCaseTypes.map(item => item.count)
|
||||||
|
|
||||||
|
return {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
formatter: function (params) {
|
||||||
|
const dataIndex = params[0].dataIndex
|
||||||
|
return `${categories[dataIndex]}: ${values[dataIndex]}件`
|
||||||
|
},
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '0%',
|
||||||
|
right: '5%',
|
||||||
|
bottom: '5%',
|
||||||
|
top: '5%',
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'value',
|
||||||
|
min: 0,
|
||||||
|
max: function (value) {
|
||||||
|
// 如果最大值是0,设置一个最小值让柱子能显示
|
||||||
|
return Math.max(value.max, 1)
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
type: 'dashed',
|
||||||
|
color: '#f0f0f0',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#666',
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#ddd',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: categories,
|
||||||
|
axisLabel: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#666',
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#ddd',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '案件数量',
|
||||||
|
type: 'bar',
|
||||||
|
barWidth: '30%',
|
||||||
|
data: values.map((value) => {
|
||||||
|
return {
|
||||||
|
value: value === 0 ? 0.1 : value, // 0值显示为0.1,让柱子能显示一个小尖尖
|
||||||
|
itemStyle: {
|
||||||
|
color: '#5d7eeb',
|
||||||
|
borderRadius: [0, 4, 4, 0],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'right',
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#666',
|
||||||
|
formatter: function (params) {
|
||||||
|
// 如果是0.1(实际为0),显示为0
|
||||||
|
return params.value === 0.1 ? '0' : params.value
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取风险概览样式
|
||||||
|
const getRiskOverviewClass = () => {
|
||||||
|
// 有高风险案件 - 红色警告
|
||||||
|
if (props.stats.highRiskItems > 0) {
|
||||||
|
return 'bg-[#F9ECEC] border border-[#F0CACA]'
|
||||||
|
}
|
||||||
|
// 有案件但无高风险 - 黄色警示
|
||||||
|
if (props.totalCases > 0) {
|
||||||
|
return 'bg-[#FFF8E1] border border-[#FFE082]'
|
||||||
|
}
|
||||||
|
// 无案件 - 绿色正常
|
||||||
|
return 'bg-[#ECF9EF] border border-[#CAECD3]'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取风险图标
|
||||||
|
const getRiskIcon = () => {
|
||||||
|
// 有高风险案件 - 高风险图标
|
||||||
|
if (props.stats.highRiskItems > 0) {
|
||||||
|
return new URL('@/assets/images/report/gfx.png', import.meta.url).href
|
||||||
|
}
|
||||||
|
// 有案件但无高风险 - 中风险图标
|
||||||
|
if (props.totalCases > 0) {
|
||||||
|
return new URL('@/assets/images/report/zfx.png', import.meta.url).href
|
||||||
|
}
|
||||||
|
// 无案件 - 正常图标
|
||||||
|
return new URL('@/assets/images/report/zq.png', import.meta.url).href
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
457
report-viewer/src/ui/FLXG7E8F/index.vue
Normal file
457
report-viewer/src/ui/FLXG7E8F/index.vue
Normal file
@@ -0,0 +1,457 @@
|
|||||||
|
<template>
|
||||||
|
<div class="card shadow-sm rounded-xl overflow-hidden p-4">
|
||||||
|
<div class="border border-[#EEEEEE] rounded-xl">
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="flex items-center mb-3 p-4">
|
||||||
|
<div class="w-8 h-8 flex items-center justify-center mr-2">
|
||||||
|
<img src="@/assets/images/report/ssfxfx.png" alt="个人涉诉风险" class="w-8 h-8 object-contain" />
|
||||||
|
</div>
|
||||||
|
<span class="font-bold text-gray-800">个人涉诉风险分析</span>
|
||||||
|
</div>
|
||||||
|
<LTitle title="涉诉风险整体概览" />
|
||||||
|
<!-- 全局风险概览面板 -->
|
||||||
|
<StatisticsOverview class="" v-if="totalCases > 0 && lawsuitStats" :stats="lawsuitStats"
|
||||||
|
:total-cases="totalCases" />
|
||||||
|
|
||||||
|
<!-- 案件类型筛选tab -->
|
||||||
|
<div v-if="totalCases > 0" class="p-4">
|
||||||
|
<van-tabs v-model:active="activeCaseTypeFilter" line-width="30px" swipeable class="lawsuit-tabs">
|
||||||
|
<!-- 全部风险 -->
|
||||||
|
<van-tab name="all">
|
||||||
|
<template #title>
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<span>全部风险</span>
|
||||||
|
<span>({{ caseTypeCounts.all }})</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-tab>
|
||||||
|
|
||||||
|
<!-- 各类型案件 - 使用v-for渲染 -->
|
||||||
|
<van-tab v-for="(typeInfo, type) in lawsuitTypeMap" :key="type" :name="type">
|
||||||
|
<template #title>
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<span>{{ typeInfo.text }}({{ caseTypeCounts[type] || 0 }})</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div v-if="filteredCases.length === 0" class="p-8 text-center text-gray-500">
|
||||||
|
<div class="flex flex-col items-center justify-center">
|
||||||
|
<van-empty :description="`暂无${typeInfo.text}记录`" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-tab>
|
||||||
|
</van-tabs>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 案件列表 -->
|
||||||
|
<div v-if="filteredCases.length > 0" class="space-y-3 px-4 mb-4">
|
||||||
|
<div v-for="(caseItem, index) in filteredCases" :key="index" class="case-wrapper">
|
||||||
|
<!-- 案件卡片 - 可点击展开 -->
|
||||||
|
<div class="bg-white rounded-xl overflow-hidden border px-4 pt-3 border-[#DDDDDD]">
|
||||||
|
<div class="cursor-pointer relative" @click="toggleCaseExpand(caseItem.id || index, 'case', index)">
|
||||||
|
<!-- 顶部区域:案件标题和案件类型 -->
|
||||||
|
<div class=" flex items-center">
|
||||||
|
<!-- 案件标题 -->
|
||||||
|
<div class="font-bold text-base text-[#333333] mr-2">{{ caseItem.c_ah || caseItem.caseNumber || '暂无案号' }}</div>
|
||||||
|
|
||||||
|
<!-- 案件类型标签 -->
|
||||||
|
<span class="px-2 py-1 text-sm rounded-md font-medium bg-[#F9ECEC] text-[#EB3C3C]">
|
||||||
|
{{ getCaseTypeText(caseItem.type) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 中间区域:立案时间 -->
|
||||||
|
<div class="pb-2">
|
||||||
|
<span class="text-sm text-[#666666]">立案:</span>
|
||||||
|
<span class="text-sm text-[#333333]">{{ formatDate(caseItem.d_larq || caseItem.fileDate) }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部区域:风险等级和案件状态 -->
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<!-- 风险等级标签 -->
|
||||||
|
<span class="px-2 py-1 text-sm rounded-md font-medium"
|
||||||
|
:class="getCaseTypeRiskLevel(caseItem.type).color">
|
||||||
|
{{ getCaseTypeRiskLevel(caseItem.type).text }}
|
||||||
|
</span>
|
||||||
|
<!-- 案件状态标签 -->
|
||||||
|
<span v-if="caseItem.n_ajjzjd" class="px-2 py-1 text-sm rounded-md font-medium"
|
||||||
|
:class="getCaseStatusClass(caseItem.n_ajjzjd)">
|
||||||
|
{{ caseItem.n_ajjzjd }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 展开指示器 -->
|
||||||
|
<div class="absolute right-4 bottom-3 flex items-center text-sm text-gray-500">
|
||||||
|
<img src="@/assets/images/report/zk.png" alt="展开" class="w-4 h-4 container"
|
||||||
|
:class="{ 'rotate-180': isCaseExpanded(caseItem.id || index, 'case', index) }" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 案件详情抽屉 -->
|
||||||
|
<div class="mt-4 overflow-hidden transition-all duration-300 ease-in-out" :class="{
|
||||||
|
'max-h-0 opacity-0': !isCaseExpanded(caseItem.id || index, 'case', index),
|
||||||
|
'max-h-none opacity-100': isCaseExpanded(caseItem.id || index, 'case', index),
|
||||||
|
}">
|
||||||
|
<div class="mt-1 transform transition-all duration-300">
|
||||||
|
<div class="relative">
|
||||||
|
<CaseDetail :case-data="caseItem" :type-color="getCaseTypeColor(caseItem.type)"
|
||||||
|
:case-type="caseItem.type" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 无涉诉风险时的空状态展示 -->
|
||||||
|
<div v-else class="text-gray-500 py-10 text-center bg-gray-50 rounded-lg mx-4 mb-4">
|
||||||
|
<div class="text-gray-300 text-3xl mb-2">⚖️</div>
|
||||||
|
暂无涉诉风险记录
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed, onMounted, watch } from 'vue'
|
||||||
|
import LTitle from '@/components/LTitle.vue'
|
||||||
|
import LRemark from '@/components/LRemark.vue'
|
||||||
|
import StatisticsOverview from './components/StatisticsOverview.vue'
|
||||||
|
import CaseDetail from './components/CaseDetail.vue'
|
||||||
|
import { useRiskNotifier } from '@/composables/useRiskNotifier'
|
||||||
|
import {
|
||||||
|
lawsuitTypeMap,
|
||||||
|
getCaseTypeText,
|
||||||
|
getCaseTypeColor,
|
||||||
|
getRiskLevel,
|
||||||
|
getCaseStatusClass,
|
||||||
|
formatDate,
|
||||||
|
getLawsuitStats,
|
||||||
|
getCaseTypeRiskLevel,
|
||||||
|
} from './utils/lawsuitUtils.js'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
apiId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
index: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
notifyRiskStatus: {
|
||||||
|
type: Function,
|
||||||
|
default: () => { },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取 judicial_data 数据
|
||||||
|
const judicialData = computed(() => {
|
||||||
|
return props.data?.data?.judicial_data || props.data?.judicial_data || {}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取 lawsuitStat 数据
|
||||||
|
const lawsuitStat = computed(() => {
|
||||||
|
return judicialData.value.lawsuitStat || {
|
||||||
|
administrative: {},
|
||||||
|
bankrupt: {},
|
||||||
|
cases_tree: { criminal: [], civil: [] },
|
||||||
|
civil: {},
|
||||||
|
count: {},
|
||||||
|
criminal: { cases: [], count: {} },
|
||||||
|
implement: {},
|
||||||
|
preservation: {},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取失信列表
|
||||||
|
const breachCaseList = computed(() => {
|
||||||
|
return judicialData.value.breachCaseList || []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取限制消费列表
|
||||||
|
const consumptionRestrictionList = computed(() => {
|
||||||
|
return judicialData.value.consumptionRestrictionList || []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 用于跟踪展开的案件卡片
|
||||||
|
const expandedCases = ref({})
|
||||||
|
|
||||||
|
// 切换展开/收起案件详情
|
||||||
|
const toggleCaseExpand = (caseId, listType, index) => {
|
||||||
|
const uniqueKey = `${caseId}_${listType}_${index}`
|
||||||
|
expandedCases.value[uniqueKey] = !expandedCases.value[uniqueKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查案件是否展开
|
||||||
|
const isCaseExpanded = (caseId, listType, index) => {
|
||||||
|
const uniqueKey = `${caseId}_${listType}_${index}`
|
||||||
|
return !!expandedCases.value[uniqueKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前选中的案件类型筛选
|
||||||
|
const activeCaseTypeFilter = ref('all')
|
||||||
|
|
||||||
|
// 计算所有案件数据
|
||||||
|
const allCases = computed(() => {
|
||||||
|
const cases = []
|
||||||
|
|
||||||
|
// 添加失信被执行人案件
|
||||||
|
breachCaseList.value.forEach((item, index) => {
|
||||||
|
cases.push({
|
||||||
|
...item,
|
||||||
|
type: 'breachCase',
|
||||||
|
id: `breachCase_${index}`,
|
||||||
|
// 映射字段以保持兼容性
|
||||||
|
c_ah: item.caseNumber,
|
||||||
|
d_larq: item.fileDate,
|
||||||
|
n_ajjzjd: item.fulfillStatus === '全部未履行' ? '未结案' : '已结案',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加限高被执行人案件
|
||||||
|
consumptionRestrictionList.value.forEach((item, index) => {
|
||||||
|
cases.push({
|
||||||
|
...item,
|
||||||
|
type: 'consumptionRestriction',
|
||||||
|
id: `consumptionRestriction_${index}`,
|
||||||
|
// 映射字段以保持兼容性
|
||||||
|
c_ah: item.caseNumber,
|
||||||
|
d_larq: item.fileDate,
|
||||||
|
n_ajjzjd: '未结案', // 限高案件通常为未结案
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加其他类型案件
|
||||||
|
if (lawsuitStat.value) {
|
||||||
|
// 处理民事案件
|
||||||
|
if (lawsuitStat.value.civil && lawsuitStat.value.civil.cases) {
|
||||||
|
lawsuitStat.value.civil.cases.forEach((item, index) => {
|
||||||
|
cases.push({
|
||||||
|
...item,
|
||||||
|
type: 'civil',
|
||||||
|
id: `civil_${index}`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理刑事案件
|
||||||
|
if (lawsuitStat.value.criminal && lawsuitStat.value.criminal.cases) {
|
||||||
|
lawsuitStat.value.criminal.cases.forEach((item, index) => {
|
||||||
|
cases.push({
|
||||||
|
...item,
|
||||||
|
type: 'criminal',
|
||||||
|
id: `criminal_${index}`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理执行案件
|
||||||
|
if (lawsuitStat.value.implement && lawsuitStat.value.implement.cases) {
|
||||||
|
lawsuitStat.value.implement.cases.forEach((item, index) => {
|
||||||
|
cases.push({
|
||||||
|
...item,
|
||||||
|
type: 'implement',
|
||||||
|
id: `implement_${index}`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理行政案件
|
||||||
|
if (lawsuitStat.value.administrative && lawsuitStat.value.administrative.cases) {
|
||||||
|
lawsuitStat.value.administrative.cases.forEach((item, index) => {
|
||||||
|
cases.push({
|
||||||
|
...item,
|
||||||
|
type: 'administrative',
|
||||||
|
id: `administrative_${index}`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理破产案件
|
||||||
|
if (lawsuitStat.value.bankrupt && lawsuitStat.value.bankrupt.cases) {
|
||||||
|
lawsuitStat.value.bankrupt.cases.forEach((item, index) => {
|
||||||
|
cases.push({
|
||||||
|
...item,
|
||||||
|
type: 'bankrupt',
|
||||||
|
id: `bankrupt_${index}`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理保全案件
|
||||||
|
if (lawsuitStat.value.preservation && lawsuitStat.value.preservation.cases) {
|
||||||
|
lawsuitStat.value.preservation.cases.forEach((item, index) => {
|
||||||
|
cases.push({
|
||||||
|
...item,
|
||||||
|
type: 'preservation',
|
||||||
|
id: `preservation_${index}`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cases
|
||||||
|
})
|
||||||
|
|
||||||
|
// 计算总案件数
|
||||||
|
const totalCases = computed(() => allCases.value.length)
|
||||||
|
|
||||||
|
// 计算涉诉风险统计
|
||||||
|
const lawsuitStats = computed(() => {
|
||||||
|
if (totalCases.value === 0) return null
|
||||||
|
|
||||||
|
const stats = {
|
||||||
|
totalRiskItems: totalCases.value,
|
||||||
|
highRiskItems: 0,
|
||||||
|
mediumRiskItems: 0,
|
||||||
|
lowRiskItems: 0,
|
||||||
|
breachCaseCount: breachCaseList.value.length,
|
||||||
|
consumptionRestrictionCount: consumptionRestrictionList.value.length,
|
||||||
|
closedCases: 0,
|
||||||
|
caseTypes: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计各类型案件数量
|
||||||
|
const typeCounts = {}
|
||||||
|
Object.keys(lawsuitTypeMap).forEach(type => {
|
||||||
|
typeCounts[type] = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
allCases.value.forEach(caseItem => {
|
||||||
|
// 根据案件类型统计风险等级
|
||||||
|
const riskLevel = getCaseTypeRiskLevel(caseItem.type).level
|
||||||
|
if (riskLevel === 'high') {
|
||||||
|
stats.highRiskItems++
|
||||||
|
} else if (riskLevel === 'medium') {
|
||||||
|
stats.mediumRiskItems++
|
||||||
|
} else {
|
||||||
|
stats.lowRiskItems++
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计已结案件
|
||||||
|
if (caseItem.n_ajjzjd && caseItem.n_ajjzjd.includes('已结')) {
|
||||||
|
stats.closedCases++
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计案件类型
|
||||||
|
if (caseItem.type) {
|
||||||
|
typeCounts[caseItem.type] = (typeCounts[caseItem.type] || 0) + 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 转换为数组格式
|
||||||
|
stats.caseTypes = Object.keys(typeCounts)
|
||||||
|
.filter(type => typeCounts[type] > 0)
|
||||||
|
.map(type => ({
|
||||||
|
type,
|
||||||
|
count: typeCounts[type],
|
||||||
|
name: getCaseTypeText(type),
|
||||||
|
color: getCaseTypeColor(type),
|
||||||
|
}))
|
||||||
|
.sort((a, b) => b.count - a.count)
|
||||||
|
|
||||||
|
return stats
|
||||||
|
})
|
||||||
|
|
||||||
|
// 按案件类型筛选案件
|
||||||
|
const filteredCases = computed(() => {
|
||||||
|
if (activeCaseTypeFilter.value === 'all') {
|
||||||
|
return allCases.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return allCases.value.filter(caseItem => caseItem.type === activeCaseTypeFilter.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取每种案件类型的数量
|
||||||
|
const caseTypeCounts = computed(() => {
|
||||||
|
const counts = {
|
||||||
|
all: totalCases.value,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化所有案件类型的计数
|
||||||
|
Object.keys(lawsuitTypeMap).forEach(type => {
|
||||||
|
counts[type] = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 计算每种类型的案件数量
|
||||||
|
allCases.value.forEach(caseItem => {
|
||||||
|
if (caseItem.type) {
|
||||||
|
counts[caseItem.type]++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return counts
|
||||||
|
})
|
||||||
|
|
||||||
|
// 设置当前筛选类型
|
||||||
|
const setCaseTypeFilter = type => {
|
||||||
|
activeCaseTypeFilter.value = type
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算风险评分(0-100分,分数越高越安全)
|
||||||
|
const riskScore = computed(() => {
|
||||||
|
const cases = totalCases.value;
|
||||||
|
|
||||||
|
// 根据涉诉案件数量计算评分
|
||||||
|
// 0件:100分(最安全)
|
||||||
|
// 1-2件:70分(中等风险)
|
||||||
|
// 3-5件:50分(较高风险)
|
||||||
|
// 6-10件:30分(高风险)
|
||||||
|
// 10件以上:10分(极高风险)
|
||||||
|
if (cases === 0) return 100;
|
||||||
|
if (cases <= 2) return 70;
|
||||||
|
if (cases <= 5) return 50;
|
||||||
|
if (cases <= 10) return 30;
|
||||||
|
return 10;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 使用 composable 通知父组件风险评分
|
||||||
|
useRiskNotifier(props, riskScore);
|
||||||
|
|
||||||
|
// 暴露给父组件
|
||||||
|
defineExpose({
|
||||||
|
riskScore
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.case-wrapper {
|
||||||
|
@apply relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lawsuit-tabs :deep(.van-tabs__wrap) {
|
||||||
|
height: 32px !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
border-bottom: 1px solid #DDDDDD !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lawsuit-tabs :deep(.van-tabs__nav) {
|
||||||
|
background-color: transparent !important;
|
||||||
|
gap: 0;
|
||||||
|
height: 32px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lawsuit-tabs :deep(.van-tab) {
|
||||||
|
color: #999999 !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-weight: 400 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lawsuit-tabs :deep(.van-tab--active) {
|
||||||
|
color: var(--van-theme-primary) !important;
|
||||||
|
background-color: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lawsuit-tabs :deep(.van-tabs__line) {
|
||||||
|
height: 3px !important;
|
||||||
|
border-radius: 1px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
303
report-viewer/src/ui/FLXG7E8F/utils/lawsuitUtils.js
Normal file
303
report-viewer/src/ui/FLXG7E8F/utils/lawsuitUtils.js
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
// 案件类型映射表
|
||||||
|
export const lawsuitTypeMap = {
|
||||||
|
breachCase: {
|
||||||
|
text: '失信被执行',
|
||||||
|
color: 'text-red-600 bg-red-50',
|
||||||
|
darkColor: 'bg-red-500',
|
||||||
|
riskLevel: 'high', // 高风险
|
||||||
|
},
|
||||||
|
consumptionRestriction: {
|
||||||
|
text: '限高被执行',
|
||||||
|
color: 'text-orange-600 bg-orange-50',
|
||||||
|
darkColor: 'bg-orange-500',
|
||||||
|
riskLevel: 'high', // 高风险
|
||||||
|
},
|
||||||
|
criminal: {
|
||||||
|
text: '刑事案件',
|
||||||
|
color: 'text-red-600 bg-red-50',
|
||||||
|
darkColor: 'bg-red-500',
|
||||||
|
riskLevel: 'high', // 高风险
|
||||||
|
},
|
||||||
|
civil: {
|
||||||
|
text: '民事案件',
|
||||||
|
color: 'text-blue-600 bg-blue-50',
|
||||||
|
darkColor: 'bg-blue-500',
|
||||||
|
riskLevel: 'medium', // 中风险
|
||||||
|
},
|
||||||
|
administrative: {
|
||||||
|
text: '行政案件',
|
||||||
|
color: 'text-purple-600 bg-purple-50',
|
||||||
|
darkColor: 'bg-purple-500',
|
||||||
|
riskLevel: 'medium', // 中风险
|
||||||
|
},
|
||||||
|
implement: {
|
||||||
|
text: '执行案件',
|
||||||
|
color: 'text-orange-600 bg-orange-50',
|
||||||
|
darkColor: 'bg-orange-500',
|
||||||
|
riskLevel: 'medium', // 中风险
|
||||||
|
},
|
||||||
|
bankrupt: {
|
||||||
|
text: '强制清算与破产案件',
|
||||||
|
color: 'text-rose-600 bg-rose-50',
|
||||||
|
darkColor: 'bg-rose-500',
|
||||||
|
riskLevel: 'high', // 高风险
|
||||||
|
},
|
||||||
|
preservation: {
|
||||||
|
text: '非诉保全审查',
|
||||||
|
color: 'text-amber-600 bg-amber-50',
|
||||||
|
darkColor: 'bg-amber-500',
|
||||||
|
riskLevel: 'low', // 低风险
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 案件类型文本
|
||||||
|
export const getCaseTypeText = type => {
|
||||||
|
return lawsuitTypeMap[type]?.text || '其他案件'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 案件类型颜色
|
||||||
|
export const getCaseTypeColor = type => {
|
||||||
|
return lawsuitTypeMap[type]?.color || 'text-gray-600 bg-gray-50'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 案件类型深色
|
||||||
|
export const getCaseTypeDarkColor = type => {
|
||||||
|
return lawsuitTypeMap[type]?.darkColor || 'bg-gray-500'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化日期显示
|
||||||
|
export const formatDate = dateStr => {
|
||||||
|
if (!dateStr) return '—'
|
||||||
|
// 转换YYYY-MM-DD为年月日格式
|
||||||
|
if (dateStr.includes('-')) {
|
||||||
|
const parts = dateStr.split('-')
|
||||||
|
if (parts.length === 3) {
|
||||||
|
return `${parts[0]}年${parts[1]}月${parts[2]}日`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dateStr // 如果不是标准格式则返回原始字符串
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化金额显示(单位:万元)
|
||||||
|
export const formatLawsuitMoney = money => {
|
||||||
|
if (!money) return '—'
|
||||||
|
|
||||||
|
const value = parseFloat(money)
|
||||||
|
if (isNaN(value)) return '—'
|
||||||
|
|
||||||
|
// 超过1亿显示亿元
|
||||||
|
if (value >= 10000) {
|
||||||
|
return (
|
||||||
|
(value / 10000).toLocaleString('zh-CN', {
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
}) + ' 亿元'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则显示万元
|
||||||
|
return (
|
||||||
|
value.toLocaleString('zh-CN', {
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
}) + ' 万元'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取案件状态样式
|
||||||
|
export const getCaseStatusClass = status => {
|
||||||
|
if (!status) return 'bg-gray-100 text-gray-500'
|
||||||
|
|
||||||
|
if (status.includes('已结') || status.includes('已办结')) {
|
||||||
|
return 'bg-green-50 text-green-600'
|
||||||
|
} else if (status.includes('执行中') || status.includes('审理中')) {
|
||||||
|
return 'bg-blue-50 text-blue-600'
|
||||||
|
} else if (status.includes('未执行')) {
|
||||||
|
return 'bg-amber-50 text-amber-600'
|
||||||
|
} else {
|
||||||
|
return 'bg-gray-100 text-gray-500'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取企业状态对应的样式
|
||||||
|
export const getStatusClass = status => {
|
||||||
|
if (!status) return 'bg-gray-100 text-gray-500'
|
||||||
|
|
||||||
|
if (status.includes('注销') || status.includes('吊销')) {
|
||||||
|
return 'bg-red-50 text-red-600'
|
||||||
|
} else if (status.includes('存续') || status.includes('在营')) {
|
||||||
|
return 'bg-green-50 text-green-600'
|
||||||
|
} else if (status.includes('筹建') || status.includes('新设')) {
|
||||||
|
return 'bg-blue-50 text-blue-600'
|
||||||
|
} else {
|
||||||
|
return 'bg-yellow-50 text-yellow-600'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化资本金额显示
|
||||||
|
export const formatCapital = (capital, currency) => {
|
||||||
|
if (!capital) return '—'
|
||||||
|
|
||||||
|
// 检查是否包含"万"字或需要显示为万元
|
||||||
|
let unit = ''
|
||||||
|
let value = parseFloat(capital)
|
||||||
|
|
||||||
|
// 处理原始数据中可能带有的单位
|
||||||
|
if (typeof capital === 'string' && capital.includes('万')) {
|
||||||
|
unit = '万'
|
||||||
|
// 提取数字部分
|
||||||
|
const numMatch = capital.match(/[\d.]+/)
|
||||||
|
value = numMatch ? parseFloat(numMatch[0]) : 0
|
||||||
|
} else if (value >= 10000) {
|
||||||
|
// 大额数字转换为万元显示
|
||||||
|
value = value / 10000
|
||||||
|
unit = '万'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化数字,保留两位小数(如果有小数部分)
|
||||||
|
const formattedValue = value.toLocaleString('zh-CN', {
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
})
|
||||||
|
|
||||||
|
return `${formattedValue}${unit} ${currency || '人民币'}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取涉诉风险等级
|
||||||
|
export const getRiskLevel = lawsuitInfo => {
|
||||||
|
if (!lawsuitInfo) {
|
||||||
|
return {
|
||||||
|
level: 'low',
|
||||||
|
text: '低风险',
|
||||||
|
color: 'text-green-600 bg-green-50',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 失信被执行人是最高风险
|
||||||
|
if (lawsuitInfo.breachCaseList && lawsuitInfo.breachCaseList.length > 0) {
|
||||||
|
return {
|
||||||
|
level: 'high',
|
||||||
|
text: '高风险',
|
||||||
|
color: 'text-red-600 bg-red-50',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 限高被执行人是最高风险
|
||||||
|
if (lawsuitInfo.consumptionRestrictionList && lawsuitInfo.consumptionRestrictionList.length > 0) {
|
||||||
|
return {
|
||||||
|
level: 'high',
|
||||||
|
text: '高风险',
|
||||||
|
color: 'text-red-600 bg-red-50',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 有涉诉数据的风险级别
|
||||||
|
if (lawsuitInfo.lawsuitStat && Object.keys(lawsuitInfo.lawsuitStat).length > 0) {
|
||||||
|
// 检查是否有未结案的案件
|
||||||
|
const data = lawsuitInfo.lawsuitStat
|
||||||
|
if (data.count && data.count.count_wei_total && data.count.count_wei_total > 0) {
|
||||||
|
return {
|
||||||
|
level: 'medium',
|
||||||
|
text: '中风险',
|
||||||
|
color: 'text-amber-600 bg-amber-50',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只有已结案的为低中风险
|
||||||
|
return {
|
||||||
|
level: 'low-medium',
|
||||||
|
text: '低中风险',
|
||||||
|
color: 'text-yellow-600 bg-yellow-50',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
level: 'low',
|
||||||
|
text: '低风险',
|
||||||
|
color: 'text-green-600 bg-green-50',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取涉诉案件统计
|
||||||
|
export const getLawsuitStats = lawsuitInfo => {
|
||||||
|
if (!lawsuitInfo) return null
|
||||||
|
|
||||||
|
const stats = {
|
||||||
|
total: 0,
|
||||||
|
types: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计各类型案件数量
|
||||||
|
Object.keys(lawsuitTypeMap).forEach(type => {
|
||||||
|
let count = 0
|
||||||
|
|
||||||
|
if (type === 'breachCase') {
|
||||||
|
count = lawsuitInfo.breachCaseList && lawsuitInfo.breachCaseList.length > 0 ? lawsuitInfo.breachCaseList.length : 0
|
||||||
|
} else if (type === 'consumptionRestriction') {
|
||||||
|
count = lawsuitInfo.consumptionRestrictionList && lawsuitInfo.consumptionRestrictionList.length > 0 ? lawsuitInfo.consumptionRestrictionList.length : 0
|
||||||
|
} else if (lawsuitInfo.lawsuitStat && lawsuitInfo.lawsuitStat[type] && Object.keys(lawsuitInfo.lawsuitStat[type]).length > 0) {
|
||||||
|
const typeData = lawsuitInfo.lawsuitStat[type]
|
||||||
|
count = typeData.cases && typeData.cases.length ? typeData.cases.length : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
stats.total += count
|
||||||
|
stats.types.push({
|
||||||
|
type,
|
||||||
|
count,
|
||||||
|
name: getCaseTypeText(type),
|
||||||
|
color: getCaseTypeColor(type),
|
||||||
|
darkColor: getCaseTypeDarkColor(type),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return stats
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取案件类型优先级顺序
|
||||||
|
export const getCaseTypePriority = () => {
|
||||||
|
return [
|
||||||
|
'breachCase', // 失信被执行人(最高风险)
|
||||||
|
'consumptionRestriction', // 限高被执行人
|
||||||
|
'criminal', // 刑事案件
|
||||||
|
'civil', // 民事案件
|
||||||
|
'administrative', // 行政案件
|
||||||
|
'implement', // 执行案件
|
||||||
|
'bankrupt', // 强制清算与破产案件
|
||||||
|
'preservation', // 非诉保全审查
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据案件类型获取风险等级
|
||||||
|
export const getCaseTypeRiskLevel = caseType => {
|
||||||
|
const typeInfo = lawsuitTypeMap[caseType]
|
||||||
|
if (!typeInfo) {
|
||||||
|
return {
|
||||||
|
level: 'low',
|
||||||
|
text: '低风险',
|
||||||
|
color: 'text-green-600 bg-green-50',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const riskLevelMap = {
|
||||||
|
high: {
|
||||||
|
text: '高风险',
|
||||||
|
color: 'text-red-600 bg-red-50',
|
||||||
|
},
|
||||||
|
medium: {
|
||||||
|
text: '中风险',
|
||||||
|
color: 'text-amber-600 bg-amber-50',
|
||||||
|
},
|
||||||
|
low: {
|
||||||
|
text: '低风险',
|
||||||
|
color: 'text-green-600 bg-green-50',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
level: typeInfo.riskLevel,
|
||||||
|
...riskLevelMap[typeInfo.riskLevel],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
170
server/crawler-detector.js
Normal file
170
server/crawler-detector.js
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
/**
|
||||||
|
* 爬虫检测模块
|
||||||
|
* 用于识别搜索引擎爬虫和社交媒体爬虫
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CrawlerDetector {
|
||||||
|
constructor() {
|
||||||
|
// 常见搜索引擎爬虫User-Agent列表
|
||||||
|
this.crawlerPatterns = [
|
||||||
|
// 百度爬虫
|
||||||
|
'baiduspider',
|
||||||
|
'baiduspider-mobile',
|
||||||
|
'baiduspider-image',
|
||||||
|
'baiduspider-video',
|
||||||
|
'baiduspider-news',
|
||||||
|
'baiduboxapp',
|
||||||
|
|
||||||
|
// Google爬虫
|
||||||
|
'googlebot',
|
||||||
|
'googlebot-image',
|
||||||
|
'googlebot-news',
|
||||||
|
'googlebot-mobile',
|
||||||
|
'googlebot-video',
|
||||||
|
'google-web-snippet',
|
||||||
|
|
||||||
|
// 360搜索
|
||||||
|
'360spider',
|
||||||
|
'soha-agent',
|
||||||
|
'haosouspider',
|
||||||
|
|
||||||
|
// 搜狗搜索
|
||||||
|
'sogou spider',
|
||||||
|
'sogou news spider',
|
||||||
|
'sogou orion spider',
|
||||||
|
'sogou-blog',
|
||||||
|
|
||||||
|
// 必应
|
||||||
|
'bingbot',
|
||||||
|
'msnbot',
|
||||||
|
|
||||||
|
// 雅虎
|
||||||
|
'slurp',
|
||||||
|
|
||||||
|
// 搜搜
|
||||||
|
'sosospider',
|
||||||
|
'sosoimagespider',
|
||||||
|
|
||||||
|
// 有道
|
||||||
|
'youdaobot',
|
||||||
|
'yodaobot',
|
||||||
|
|
||||||
|
// 头条搜索
|
||||||
|
'bytedance-spider',
|
||||||
|
'toutiaospider',
|
||||||
|
|
||||||
|
// 社交媒体爬虫
|
||||||
|
'facebookexternalhit',
|
||||||
|
'facebookcatalog',
|
||||||
|
'twitterbot',
|
||||||
|
'linkedinbot',
|
||||||
|
'whatsapp',
|
||||||
|
'telegrambot',
|
||||||
|
'viber',
|
||||||
|
'line',
|
||||||
|
|
||||||
|
// 其他常见爬虫
|
||||||
|
'applebot',
|
||||||
|
'semrushbot',
|
||||||
|
'ahrefsbot',
|
||||||
|
'mj12bot',
|
||||||
|
'dotbot',
|
||||||
|
'crawler',
|
||||||
|
'spider',
|
||||||
|
'bot'
|
||||||
|
]
|
||||||
|
|
||||||
|
// 需要检测的头部字段
|
||||||
|
this.crawlerHeaders = ['x-bot', 'x-crawler', 'x-forwarded-for']
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测请求是否来自爬虫
|
||||||
|
* @param {Object} req - HTTP请求对象
|
||||||
|
* @returns {Boolean} 是否为爬虫
|
||||||
|
*/
|
||||||
|
isCrawler(req) {
|
||||||
|
const userAgent = req.headers['user-agent']?.toLowerCase() || ''
|
||||||
|
const headers = req.headers
|
||||||
|
|
||||||
|
// 1. 通过User-Agent检测
|
||||||
|
if (this.checkUserAgent(userAgent)) {
|
||||||
|
console.log(`[CrawlerDetector] 检测到爬虫 UA: ${userAgent}`)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 通过特定头部检测
|
||||||
|
if (this.checkHeaders(headers)) {
|
||||||
|
console.log(`[CrawlerDetector] 检测到爬虫 Headers`)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 通过IP地址检测(可选)
|
||||||
|
// if (this.checkIP(req.connection.remoteAddress)) {
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查User-Agent
|
||||||
|
* @param {String} userAgent
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
checkUserAgent(userAgent) {
|
||||||
|
if (!userAgent) return false
|
||||||
|
|
||||||
|
return this.crawlerPatterns.some(pattern => {
|
||||||
|
return userAgent.includes(pattern.toLowerCase())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查请求头
|
||||||
|
* @param {Object} headers
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
checkHeaders(headers) {
|
||||||
|
for (const header of this.crawlerHeaders) {
|
||||||
|
const headerValue = headers[header]?.toLowerCase()
|
||||||
|
if (headerValue && (headerValue.includes('bot') || headerValue.includes('crawler'))) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查IP地址是否为已知爬虫IP
|
||||||
|
* @param {String} ip
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
checkIP(ip) {
|
||||||
|
// 这里可以添加已知爬虫IP段的检测
|
||||||
|
// 需要定期更新爬虫IP列表
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取爬虫类型
|
||||||
|
* @param {String} userAgent
|
||||||
|
* @returns {String} 爬虫类型
|
||||||
|
*/
|
||||||
|
getCrawlerType(userAgent) {
|
||||||
|
const ua = userAgent.toLowerCase()
|
||||||
|
|
||||||
|
if (ua.includes('baiduspider')) return 'baidu'
|
||||||
|
if (ua.includes('googlebot')) return 'google'
|
||||||
|
if (ua.includes('bingbot') || ua.includes('msnbot')) return 'bing'
|
||||||
|
if (ua.includes('360spider')) return '360'
|
||||||
|
if (ua.includes('sogou spider')) return 'sogou'
|
||||||
|
if (ua.includes('facebookexternalhit')) return 'facebook'
|
||||||
|
if (ua.includes('twitterbot')) return 'twitter'
|
||||||
|
if (ua.includes('linkedinbot')) return 'linkedin'
|
||||||
|
|
||||||
|
return 'unknown'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CrawlerDetector
|
||||||
245
server/generate-seo-templates.cjs
Normal file
245
server/generate-seo-templates.cjs
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
/**
|
||||||
|
* SEO模板生成器
|
||||||
|
* 根据 useSEO.js 的页面配置自动生成静态 HTML 模板,供爬虫访问时返回
|
||||||
|
* 配置与 src/composables/useSEO.js 保持一致
|
||||||
|
*
|
||||||
|
* 多站点:通过环境变量 SEO_BASE_URL 指定 canonical/og:url 域名后生成
|
||||||
|
* 例:SEO_BASE_URL=https://www.tianyuandb.com node generate-seo-templates.cjs
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const BASE_URL = process.env.SEO_BASE_URL || 'https://www.tianyuandb.com'
|
||||||
|
|
||||||
|
// 页面 SEO 配置(与 useSEO.js 的 routeConfigs 保持一致)
|
||||||
|
const pageSEOConfigs = {
|
||||||
|
'index.html': {
|
||||||
|
title: '天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台',
|
||||||
|
description: '天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。',
|
||||||
|
keywords: '天远数据,职场背调,风险核验报告,家政背景核验,第三方背调,企业风控服务,数据报告分销',
|
||||||
|
url: BASE_URL
|
||||||
|
},
|
||||||
|
'historyQuery.html': {
|
||||||
|
title: '我的报告_历史查询记录_天远数据',
|
||||||
|
description: '天远数据用户个人中心,查看及下载历史查询报告。',
|
||||||
|
keywords: '我的报告,历史记录,天远数据',
|
||||||
|
url: `${BASE_URL}/historyQuery`
|
||||||
|
},
|
||||||
|
'inquire-personalData.html': {
|
||||||
|
title: '个人综合风险报告_个人履约评分_多维数据检测_天远数据',
|
||||||
|
description: '天远数据提供个人全维信用画像扫描。一键检测司法涉诉记录、历史履约情况、号码状态异常检测及个人消费等级。数据同步权威行业系统,采用银行级加密技术,保障信息安全,助您全面了解自身信用状况。',
|
||||||
|
keywords: '个人风险评估,信用状况评估,综合履约能力,司法风险自查,风险标签检测',
|
||||||
|
url: `${BASE_URL}/inquire/personalData`
|
||||||
|
},
|
||||||
|
'inquire-companyinfo.html': {
|
||||||
|
title: '企业信用风险评估_工商经营异常与司法诉讼核查_天远数据',
|
||||||
|
description: '天远数据提供全维度的企业商业画像。基于官方公示数据,核验目标企业的工商变更、经营异常名录、行政处罚、投融资背景及关联风险。深度评估商业履约能力,透视合作方真实状况,规避合同陷阱。',
|
||||||
|
keywords: '企业信用画像,公司经营风险,工商异常名录,企业履约评估,商业背景核验',
|
||||||
|
url: `${BASE_URL}/inquire/companyinfo`
|
||||||
|
},
|
||||||
|
'inquire-preloanbackgroundcheck.html': {
|
||||||
|
title: '综合履约评分检测_多平台履约记录分析_个人财务履约报告_天远数据',
|
||||||
|
description: '天远数据提供专业的个人履约健康度体检服务。基于多维大数据分析,检测您的综合评分波动、历史履约记录及潜在的风险标签。本服务旨在帮助用户优化个人数据画像,提升信用管理意识,不提供任何信贷金融服务。',
|
||||||
|
keywords: '综合评分检测,多重履约压力分析,履约能力评估,综合评分优化,个人数据画像',
|
||||||
|
url: `${BASE_URL}/inquire/preloanbackgroundcheck`
|
||||||
|
},
|
||||||
|
'inquire-marriage.html': {
|
||||||
|
title: '婚恋对象背景了解_司法诉讼与不良记录筛查_婚前风险评估_天远数据',
|
||||||
|
description: '天远数据提供专业的婚恋风险评估工具。基于合法的公开司法数据,深度排查法律诉讼记录、失信被执行信息及潜在的履约风险。数据来源合规,仅供个人防范参考,拒绝隐私泄露,为幸福保驾护航。',
|
||||||
|
keywords: '婚恋背景核验,婚前风险了解,司法记录核验,个人履约风险,背景核实',
|
||||||
|
url: `${BASE_URL}/inquire/marriage`
|
||||||
|
},
|
||||||
|
'inquire-backgroundcheck.html': {
|
||||||
|
title: '入职背景核验_候选人履历核验_职场信用与竞业排查_天远数据',
|
||||||
|
description: '天远数据职场风险报告助力企业构建防御体系。基于司法级大数据,一键筛查候选人司法涉诉记录、学历信息、商业利益冲突、历史违约记录及不良社会风险。官方数据,客观预警入职风险,辅助HR高效决策。',
|
||||||
|
keywords: '入职风险评估,候选人背景核验,简历真伪辨别,竞业限制核验,职场信用报告,员工风险预警',
|
||||||
|
url: `${BASE_URL}/inquire/backgroundcheck`
|
||||||
|
},
|
||||||
|
'inquire-homeservice.html': {
|
||||||
|
title: '家政人员背景核实_保姆月嫂司法风险筛查_用工安全评估_天远数据',
|
||||||
|
description: '天远数据家政风险报告,为家庭用人安全把关。通过合法大数据,快速筛查家政人员的司法诉讼、失信被执行记录及社会不良风险标签。有效识别潜在隐患,预防雇佣纠纷,让您找保姆、请月嫂更放心。',
|
||||||
|
keywords: '保姆背景核验,月嫂风险筛查,家政人员核验,育儿嫂背景核实,雇佣风险防范',
|
||||||
|
url: `${BASE_URL}/inquire/homeservice`
|
||||||
|
},
|
||||||
|
'agent.html': {
|
||||||
|
title: '天远数据代理 - 免费开通代理权限 | 大数据风险报告代理',
|
||||||
|
description: '天远数据代理平台,免费开通代理权限,享受大数据风险报告查询服务代理收益。专业的大数据风险报告、婚姻查询、个人信用评估等服务的代理合作。',
|
||||||
|
keywords: '天远数据代理, 免费代理, 大数据风险报告代理, 代理权限, 代理收益',
|
||||||
|
url: `${BASE_URL}/agent`
|
||||||
|
},
|
||||||
|
'agent-promote.html': {
|
||||||
|
title: '生成推广码_自定义价格_0成本代理查价系统_天远数据',
|
||||||
|
description: '天远数据推广中心支持代理自主设置报告价格。在此选择报告类型,自定义客户查询价,0成本生成专属推广链接或二维码。差价即为利润,实现个人风险报告的私域流量变现。',
|
||||||
|
keywords: '推广码生成,自定义查价系统,代理收益工具,代理推广链接,流量变现平台,天远数据推广',
|
||||||
|
url: `${BASE_URL}/agent/promote`
|
||||||
|
},
|
||||||
|
'agent-invitation.html': {
|
||||||
|
title: '邀请合作伙伴_发展代理享收益_推广返利计划_天远数据',
|
||||||
|
description: '天远数据推出合伙人邀请奖励机制。邀请好友注册成为合作伙伴,每单不仅可获得推广收益,还可叠加合作伙伴活跃奖励及定价差额收益。打造专属推广团队,实现收益持续增长。',
|
||||||
|
keywords: '渠道合作伙伴,商业收益管理,流量合规变现,业务推广系统,代理后台',
|
||||||
|
url: `${BASE_URL}/agent/invitation`
|
||||||
|
},
|
||||||
|
'help.html': {
|
||||||
|
title: '天远数据帮助中心_代理操作指南_推广收益计算常见问题',
|
||||||
|
description: '天远数据帮助中心提供全方位的代理操作指引。包含如何成为代理、推广报告生成教程、收益与成本计算规则及推广效率提升方案。',
|
||||||
|
keywords: '天远数据教程,代理新手指南,推广收益计算,报告推广',
|
||||||
|
url: `${BASE_URL}/help`
|
||||||
|
},
|
||||||
|
'help-guide.html': {
|
||||||
|
title: '使用指南 - 天远数据操作教程 | 功能说明',
|
||||||
|
description: '天远数据详细使用指南,包含各功能模块的操作教程、功能说明、注意事项等,让用户快速上手使用。',
|
||||||
|
keywords: '使用指南, 操作教程, 功能说明, 快速上手, 天远数据教程',
|
||||||
|
url: `${BASE_URL}/help/guide`
|
||||||
|
},
|
||||||
|
'example.html': {
|
||||||
|
title: '示例报告 - 天远数据报告展示 | 大数据风险报告样例',
|
||||||
|
description: '天远数据示例报告展示,包含大数据风险报告、婚姻状况查询、个人信用评估等服务的报告样例,让用户了解报告内容和格式。',
|
||||||
|
keywords: '示例报告, 报告展示, 报告样例, 大数据风险报告, 婚姻查询报告',
|
||||||
|
url: `${BASE_URL}/example`
|
||||||
|
},
|
||||||
|
'service.html': {
|
||||||
|
title: '客服中心 - 天远数据在线客服 | 技术支持',
|
||||||
|
description: '天远数据客服中心,提供在线客服支持、技术咨询、问题反馈等服务,确保用户获得及时有效的帮助。',
|
||||||
|
keywords: '客服中心, 在线客服, 技术支持, 问题反馈, 天远数据客服',
|
||||||
|
url: `${BASE_URL}/service`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 规范化文案:统一为中文标点,避免乱码
|
||||||
|
*/
|
||||||
|
function normalizeText(str) {
|
||||||
|
if (typeof str !== 'string') return str
|
||||||
|
return str
|
||||||
|
.replace(/\uFFFD/g, '')
|
||||||
|
.replace(/。/g, '。')
|
||||||
|
.replace(/、/g, '、')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转义 HTML 属性值
|
||||||
|
*/
|
||||||
|
function escapeAttr(str) {
|
||||||
|
if (typeof str !== 'string') return ''
|
||||||
|
return str
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成单页 HTML 模板
|
||||||
|
*/
|
||||||
|
function generateHTMLTemplate(config) {
|
||||||
|
const title = normalizeText(config.title)
|
||||||
|
const description = normalizeText(config.description)
|
||||||
|
const keywords = normalizeText(config.keywords)
|
||||||
|
const structuredData = {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'WebPage',
|
||||||
|
name: title,
|
||||||
|
description: description,
|
||||||
|
url: config.url,
|
||||||
|
mainEntity: {
|
||||||
|
'@type': 'Organization',
|
||||||
|
name: '天远数据',
|
||||||
|
url: 'https://www.tianyuandb.com/',
|
||||||
|
description: '专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
|
<title>${escapeAttr(title)}</title>
|
||||||
|
|
||||||
|
<meta name="description" content="${escapeAttr(description)}">
|
||||||
|
<meta name="keywords" content="${escapeAttr(keywords)}">
|
||||||
|
|
||||||
|
<meta property="og:title" content="${escapeAttr(title)}">
|
||||||
|
<meta property="og:description" content="${escapeAttr(description)}">
|
||||||
|
<meta property="og:url" content="${escapeAttr(config.url)}">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="天远数据">
|
||||||
|
<meta property="og:locale" content="zh_CN">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="${escapeAttr(title)}">
|
||||||
|
<meta name="twitter:description" content="${escapeAttr(description)}">
|
||||||
|
<meta name="twitter:url" content="${escapeAttr(config.url)}">
|
||||||
|
|
||||||
|
<link rel="canonical" href="${escapeAttr(config.url)}">
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
${JSON.stringify(structuredData, null, 8)}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<meta name="googlebot" content="index, follow">
|
||||||
|
<meta name="baiduspider" content="index, follow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; }
|
||||||
|
.seo-content { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
p { color: #666; }
|
||||||
|
.redirect-notice { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 10px; margin: 20px 0; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="seo-content">
|
||||||
|
<h1>${escapeAttr(title)}</h1>
|
||||||
|
<div class="redirect-notice">
|
||||||
|
<p>正在跳转到完整版网站...</p>
|
||||||
|
<p>如果浏览器没有自动跳转,请 <a href="${escapeAttr(config.url)}">点击这里</a></p>
|
||||||
|
</div>
|
||||||
|
<p>${escapeAttr(description)}</p>
|
||||||
|
<section>
|
||||||
|
<h2>关于天远数据</h2>
|
||||||
|
<p>天远数据提供背调报告代理加盟与个人风控系统搭建,合规数据服务平台。支持职场背调、家政背景核验、企业风控服务与数据报告分销。</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>核心服务</h2>
|
||||||
|
<ul>
|
||||||
|
<li>个人综合风险报告与履约评分</li>
|
||||||
|
<li>企业信用风险评估与工商核查</li>
|
||||||
|
<li>综合履约评分与贷前风险检测</li>
|
||||||
|
<li>婚恋对象背景了解与婚前风险评估</li>
|
||||||
|
<li>入职背景核验与职场信用排查</li>
|
||||||
|
<li>家政人员背景核实与用工安全评估</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>`
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const outputDir = path.join(__dirname, '../public/seo-templates')
|
||||||
|
|
||||||
|
if (!fs.existsSync(outputDir)) {
|
||||||
|
fs.mkdirSync(outputDir, { recursive: true })
|
||||||
|
console.log(`✓ 创建模板目录: ${outputDir}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
let successCount = 0
|
||||||
|
Object.entries(pageSEOConfigs).forEach(([filename, config]) => {
|
||||||
|
const htmlContent = generateHTMLTemplate(config)
|
||||||
|
const filePath = path.join(outputDir, filename)
|
||||||
|
fs.writeFileSync(filePath, htmlContent, 'utf-8')
|
||||||
|
console.log(`✓ 生成模板: ${filename}`)
|
||||||
|
successCount++
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(`\n✓ 成功生成 ${successCount} 个 SEO 模板文件`)
|
||||||
|
console.log(`📁 模板目录: ${outputDir}`)
|
||||||
|
console.log(`💡 配置与 useSEO.js 一致,当前域名: ${BASE_URL}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
179
server/middleware.js
Normal file
179
server/middleware.js
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
/**
|
||||||
|
* SEO中间件
|
||||||
|
* 用于在Node.js服务器中检测爬虫并返回静态HTML
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
const CrawlerDetector = require('./crawler-detector')
|
||||||
|
|
||||||
|
class SEOMiddleware {
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.detector = new CrawlerDetector()
|
||||||
|
this.templateDir = options.templateDir || path.join(__dirname, '../public/seo-templates')
|
||||||
|
this.defaultTemplate = options.defaultTemplate || 'index.html'
|
||||||
|
this.fallbackToSPA = options.fallbackToSPA !== false
|
||||||
|
this.debug = options.debug || false
|
||||||
|
|
||||||
|
// 路由到模板的映射(与 useSEO.js 及 generate-seo-templates.cjs 保持一致;子路径放前面以优先精确匹配)
|
||||||
|
this.routeTemplateMap = {
|
||||||
|
'/': 'index.html',
|
||||||
|
'/historyQuery': 'historyQuery.html',
|
||||||
|
'/agent/promote': 'agent-promote.html',
|
||||||
|
'/agent/invitation': 'agent-invitation.html',
|
||||||
|
'/agent': 'agent.html',
|
||||||
|
'/help/guide': 'help-guide.html',
|
||||||
|
'/help': 'help.html',
|
||||||
|
'/example': 'example.html',
|
||||||
|
'/service': 'service.html',
|
||||||
|
'/inquire/personalData': 'inquire-personalData.html',
|
||||||
|
'/inquire/companyinfo': 'inquire-companyinfo.html',
|
||||||
|
'/inquire/preloanbackgroundcheck': 'inquire-preloanbackgroundcheck.html',
|
||||||
|
'/inquire/marriage': 'inquire-marriage.html',
|
||||||
|
'/inquire/backgroundcheck': 'inquire-backgroundcheck.html',
|
||||||
|
'/inquire/homeservice': 'inquire-homeservice.html'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化模板缓存
|
||||||
|
this.templateCache = new Map()
|
||||||
|
this.cacheTemplates()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存所有模板文件
|
||||||
|
*/
|
||||||
|
cacheTemplates() {
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(this.templateDir)) {
|
||||||
|
console.warn(`[SEOMiddleware] 模板目录不存在: ${this.templateDir}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = fs.readdirSync(this.templateDir)
|
||||||
|
files.forEach(file => {
|
||||||
|
const filePath = path.join(this.templateDir, file)
|
||||||
|
if (fs.statSync(filePath).isFile()) {
|
||||||
|
this.templateCache.set(file, fs.readFileSync(filePath, 'utf-8'))
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(`[SEOMiddleware] 已缓存模板: ${file}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(`[SEOMiddleware] 已缓存 ${this.templateCache.size} 个模板文件`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[SEOMiddleware] 缓存模板失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对应的模板文件名
|
||||||
|
* @param {String} path - 请求路径
|
||||||
|
* @returns {String} 模板文件名
|
||||||
|
*/
|
||||||
|
getTemplatePath(requestPath) {
|
||||||
|
// 完全匹配
|
||||||
|
if (this.routeTemplateMap[requestPath]) {
|
||||||
|
return this.routeTemplateMap[requestPath]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模糊匹配(处理动态路由)
|
||||||
|
const matchedKey = Object.keys(this.routeTemplateMap).find(route => {
|
||||||
|
return requestPath.startsWith(route)
|
||||||
|
})
|
||||||
|
|
||||||
|
return matchedKey ? this.routeTemplateMap[matchedKey] : this.defaultTemplate
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板内容
|
||||||
|
* @param {String} templateName - 模板文件名
|
||||||
|
* @returns {String|null} 模板内容
|
||||||
|
*/
|
||||||
|
getTemplate(templateName) {
|
||||||
|
// 首先尝试缓存
|
||||||
|
let content = this.templateCache.get(templateName)
|
||||||
|
|
||||||
|
// 如果缓存中没有,尝试从磁盘读取
|
||||||
|
if (!content) {
|
||||||
|
try {
|
||||||
|
const filePath = path.join(this.templateDir, templateName)
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
content = fs.readFileSync(filePath, 'utf-8')
|
||||||
|
this.templateCache.set(templateName, content)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[SEOMiddleware] 读取模板失败: ${templateName}`, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return content || null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Express中间件
|
||||||
|
*/
|
||||||
|
express() {
|
||||||
|
return (req, res, next) => {
|
||||||
|
// 检测是否为爬虫
|
||||||
|
if (this.detector.isCrawler(req)) {
|
||||||
|
const templateName = this.getTemplatePath(req.path)
|
||||||
|
const template = this.getTemplate(templateName)
|
||||||
|
|
||||||
|
if (template) {
|
||||||
|
// 设置响应头
|
||||||
|
res.setHeader('Content-Type', 'text/html; charset=utf-8')
|
||||||
|
res.setHeader('X-SEOMiddleware', 'prerendered')
|
||||||
|
|
||||||
|
// 返回静态HTML
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(`[SEOMiddleware] 返回SEO模板: ${templateName} for ${req.path}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.send(template)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不是爬虫或模板不存在,继续处理SPA
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Koa中间件
|
||||||
|
*/
|
||||||
|
koa() {
|
||||||
|
return async (ctx, next) => {
|
||||||
|
// 检测是否为爬虫
|
||||||
|
if (this.detector.isCrawler(ctx.req)) {
|
||||||
|
const templateName = this.getTemplatePath(ctx.path)
|
||||||
|
const template = this.getTemplate(templateName)
|
||||||
|
|
||||||
|
if (template) {
|
||||||
|
ctx.type = 'text/html; charset=utf-8'
|
||||||
|
ctx.set('X-SEOMiddleware', 'prerendered')
|
||||||
|
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(`[SEOMiddleware] 返回SEO模板: ${templateName} for ${ctx.path}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.body = template
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新加载模板缓存
|
||||||
|
*/
|
||||||
|
reloadCache() {
|
||||||
|
this.templateCache.clear()
|
||||||
|
this.cacheTemplates()
|
||||||
|
console.log('[SEOMiddleware] 模板缓存已重新加载')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = SEOMiddleware
|
||||||
27
server/package.json
Normal file
27
server/package.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "tydata-seo-server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "SPA SEO 优化 - 爬虫检测与静态 HTML 回退,与 useSEO.js 同步",
|
||||||
|
"main": "server-example-express.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node server-example-express.js",
|
||||||
|
"dev": "node server-example-express.js",
|
||||||
|
"generate": "node generate-seo-templates.cjs",
|
||||||
|
"test": "node test-seo.js",
|
||||||
|
"test:crawler": "node test-crawler-detection.js"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"seo",
|
||||||
|
"crawler",
|
||||||
|
"spa",
|
||||||
|
"prerender"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"compression": "^1.7.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^3.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import { useDialogStore } from "@/stores/dialogStore";
|
|||||||
import { useAuthStore } from "@/stores/authStore";
|
import { useAuthStore } from "@/stores/authStore";
|
||||||
import { useWeixinShare } from "@/composables/useWeixinShare";
|
import { useWeixinShare } from "@/composables/useWeixinShare";
|
||||||
import WechatOverlay from "@/components/WechatOverlay.vue";
|
import WechatOverlay from "@/components/WechatOverlay.vue";
|
||||||
|
// import MaintenanceDialog from "@/components/MaintenanceDialog.vue";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const agentStore = useAgentStore();
|
const agentStore = useAgentStore();
|
||||||
@@ -207,8 +208,9 @@ const h5WeixinGetCode = () => {
|
|||||||
<template>
|
<template>
|
||||||
<RouterView />
|
<RouterView />
|
||||||
|
|
||||||
<WechatOverlay />
|
<WechatOverlay />
|
||||||
<BindPhoneDialog />
|
<BindPhoneDialog />
|
||||||
|
<!-- <MaintenanceDialog /> -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
1
src/auto-imports.d.ts
vendored
1
src/auto-imports.d.ts
vendored
@@ -117,6 +117,7 @@ declare global {
|
|||||||
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
|
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
|
||||||
const useAgent: typeof import('./composables/useAgent.js')['useAgent']
|
const useAgent: typeof import('./composables/useAgent.js')['useAgent']
|
||||||
const useAgentStore: typeof import('./stores/agentStore.js')['useAgentStore']
|
const useAgentStore: typeof import('./stores/agentStore.js')['useAgentStore']
|
||||||
|
const useAliyunCaptcha: typeof import('./composables/useAliyunCaptcha.js')['default']
|
||||||
const useAnimate: typeof import('@vueuse/core')['useAnimate']
|
const useAnimate: typeof import('@vueuse/core')['useAnimate']
|
||||||
const useApiFetch: typeof import('./composables/useApiFetch.js')['default']
|
const useApiFetch: typeof import('./composables/useApiFetch.js')['default']
|
||||||
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
|
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ const router = useRouter();
|
|||||||
const show = defineModel("show");
|
const show = defineModel("show");
|
||||||
import { useCascaderAreaData } from "@vant/area-data";
|
import { useCascaderAreaData } from "@vant/area-data";
|
||||||
import { showToast } from "vant"; // 引入 showToast 方法
|
import { showToast } from "vant"; // 引入 showToast 方法
|
||||||
|
import { useAliyunCaptcha } from "@/composables/useAliyunCaptcha";
|
||||||
const emit = defineEmits(); // 确保 emit 可以正确使用
|
const emit = defineEmits(); // 确保 emit 可以正确使用
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
ancestor: {
|
ancestor: {
|
||||||
@@ -158,6 +159,8 @@ const isPhoneNumberValid = computed(() => {
|
|||||||
return /^1[3-9]\d{9}$/.test(form.value.mobile);
|
return /^1[3-9]\d{9}$/.test(form.value.mobile);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { runWithCaptcha } = useAliyunCaptcha();
|
||||||
|
|
||||||
const getSmsCode = async () => {
|
const getSmsCode = async () => {
|
||||||
if (!form.value.mobile) {
|
if (!form.value.mobile) {
|
||||||
showToast({ message: "请输入手机号" });
|
showToast({ message: "请输入手机号" });
|
||||||
@@ -170,21 +173,21 @@ const getSmsCode = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadingSms.value = true;
|
loadingSms.value = true;
|
||||||
|
await runWithCaptcha(
|
||||||
const { data, error } = await useApiFetch("auth/sendSms")
|
(captchaVerifyParam) =>
|
||||||
.post({ mobile: form.value.mobile, actionType: "agentApply" })
|
useApiFetch("auth/sendSms")
|
||||||
.json();
|
.post({ mobile: form.value.mobile, actionType: "agentApply", captchaVerifyParam })
|
||||||
|
.json(),
|
||||||
loadingSms.value = false;
|
(res) => {
|
||||||
|
loadingSms.value = false;
|
||||||
if (data.value && !error.value) {
|
if (res.code === 200) {
|
||||||
if (data.value.code === 200) {
|
showToast({ message: "获取成功" });
|
||||||
showToast({ message: "获取成功" });
|
startCountdown();
|
||||||
startCountdown(); // 启动倒计时
|
} else {
|
||||||
} else {
|
showToast(res.msg);
|
||||||
showToast(data.value.msg);
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
};
|
};
|
||||||
let timer = null;
|
let timer = null;
|
||||||
|
|
||||||
|
|||||||
@@ -259,6 +259,11 @@ const featureMap = {
|
|||||||
import("@/ui/CJRZQ8203.vue")
|
import("@/ui/CJRZQ8203.vue")
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
IVYZ0S0D: {
|
||||||
|
name: "劳动仲裁信息",
|
||||||
|
component: defineAsyncComponent(() => import("@/ui/IVYZ0S0D.vue")),
|
||||||
|
remark: '劳动仲裁信息展示被查询人在失信限高、劳动争议、社会保险、福利待遇、人事争议、仲裁流程及通知函触达等方面的风险信息。',
|
||||||
|
},
|
||||||
FLXG3D56: {
|
FLXG3D56: {
|
||||||
name: "违约失信",
|
name: "违约失信",
|
||||||
component: defineAsyncComponent(() => import("@/ui/CFLXG3D56.vue")),
|
component: defineAsyncComponent(() => import("@/ui/CFLXG3D56.vue")),
|
||||||
@@ -372,10 +377,10 @@ const featureMap = {
|
|||||||
name: "逾期风险综述",
|
name: "逾期风险综述",
|
||||||
component: defineAsyncComponent(() => import("@/ui/CDWBG8B4D/components/OverdueRiskSection.vue")),
|
component: defineAsyncComponent(() => import("@/ui/CDWBG8B4D/components/OverdueRiskSection.vue")),
|
||||||
},
|
},
|
||||||
// DWBG8B4D_CourtInfo: {
|
DWBG8B4D_CourtInfo: {
|
||||||
// name: "法院曝光台信息",
|
name: "法院曝光台信息",
|
||||||
// component: defineAsyncComponent(() => import("@/ui/CDWBG8B4D/components/MultCourtInfoSection.vue")),
|
component: defineAsyncComponent(() => import("@/ui/CDWBG8B4D/components/MultCourtInfoSection.vue")),
|
||||||
// },
|
},
|
||||||
DWBG8B4D_LoanEvaluation: {
|
DWBG8B4D_LoanEvaluation: {
|
||||||
name: "借贷评估",
|
name: "借贷评估",
|
||||||
component: defineAsyncComponent(() => import("@/ui/CDWBG8B4D/components/LoanEvaluationSection.vue")),
|
component: defineAsyncComponent(() => import("@/ui/CDWBG8B4D/components/LoanEvaluationSection.vue")),
|
||||||
@@ -461,10 +466,10 @@ const featureMap = {
|
|||||||
name: "关联风险监督",
|
name: "关联风险监督",
|
||||||
component: defineAsyncComponent(() => import("@/ui/DWBG6A2C/components/RiskSupervisionSection.vue")),
|
component: defineAsyncComponent(() => import("@/ui/DWBG6A2C/components/RiskSupervisionSection.vue")),
|
||||||
},
|
},
|
||||||
// DWBG6A2C_CourtRiskInfo: {
|
DWBG6A2C_CourtRiskInfo: {
|
||||||
// name: "法院风险信息",
|
name: "法院风险信息",
|
||||||
// component: defineAsyncComponent(() => import("@/ui/DWBG6A2C/components/CourtRiskInfoSection.vue")),
|
component: defineAsyncComponent(() => import("@/ui/DWBG6A2C/components/CourtRiskInfoSection.vue")),
|
||||||
// },
|
},
|
||||||
// 贷款风险报告
|
// 贷款风险报告
|
||||||
JRZQ5E9F: {
|
JRZQ5E9F: {
|
||||||
name: "贷款风险评估",
|
name: "贷款风险评估",
|
||||||
@@ -499,7 +504,12 @@ const featureMap = {
|
|||||||
CJRZQ5E9F_RiskAdvice: {
|
CJRZQ5E9F_RiskAdvice: {
|
||||||
name: "专业建议",
|
name: "专业建议",
|
||||||
component: defineAsyncComponent(() => import("@/ui/CJRZQ5E9F/components/RiskAdvice.vue")),
|
component: defineAsyncComponent(() => import("@/ui/CJRZQ5E9F/components/RiskAdvice.vue")),
|
||||||
}
|
},
|
||||||
|
JRZQ8B3C: {
|
||||||
|
name: "个人消费等级",
|
||||||
|
component: defineAsyncComponent(() => import("@/ui/JRZQ8B3C/index.vue")),
|
||||||
|
},
|
||||||
|
IVYZ6M8P: { name: "职业资格证书查询", component: defineAsyncComponent(() => import("@/ui/CIVYZ6M8P.vue")) },
|
||||||
};
|
};
|
||||||
|
|
||||||
const maskValue = computed(() => {
|
const maskValue = computed(() => {
|
||||||
@@ -586,12 +596,15 @@ const featureRiskLevels = {
|
|||||||
'QYGL3F8E': 5, // 人企关系加强版
|
'QYGL3F8E': 5, // 人企关系加强版
|
||||||
'QCXG7A2B': 5, // 名下车辆
|
'QCXG7A2B': 5, // 名下车辆
|
||||||
'JRZQ09J8': 5, // 收入评估
|
'JRZQ09J8': 5, // 收入评估
|
||||||
|
'IVYZ0S0D': 10, // 劳动仲裁信息
|
||||||
|
'IVYZ6M8P': 5,
|
||||||
|
|
||||||
// 🔵 低风险类 - 权重 3
|
// 🔵 低风险类 - 权重 3
|
||||||
'IVYZ5733': 3, // 婚姻状态
|
'IVYZ5733': 3, // 婚姻状态
|
||||||
'IVYZ9A2B': 3, // 学历信息
|
'IVYZ9A2B': 3, // 学历信息
|
||||||
'IVYZ3P9M': 3, // 学历信息查询(实时版)
|
'IVYZ3P9M': 3, // 学历信息查询(实时版)
|
||||||
|
|
||||||
|
'JRZQ8B3C': 3, // 个人消费等级
|
||||||
// 📊 复合报告类 - 按子模块动态计算
|
// 📊 复合报告类 - 按子模块动态计算
|
||||||
'DWBG8B4D': 0, // 谛听多维报告(由子模块计算)
|
'DWBG8B4D': 0, // 谛听多维报告(由子模块计算)
|
||||||
'DWBG6A2C': 0, // 司南报告(由子模块计算)
|
'DWBG6A2C': 0, // 司南报告(由子模块计算)
|
||||||
@@ -607,6 +620,7 @@ const featureRiskLevels = {
|
|||||||
'DWBG8B4D_LeasingRisk': 6,
|
'DWBG8B4D_LeasingRisk': 6,
|
||||||
'DWBG8B4D_RiskSupervision': 8,
|
'DWBG8B4D_RiskSupervision': 8,
|
||||||
'DWBG8B4D_RiskWarningTab': 9,
|
'DWBG8B4D_RiskWarningTab': 9,
|
||||||
|
'DWBG8B4D_CourtInfo': 9,
|
||||||
|
|
||||||
// 司南报告子模块
|
// 司南报告子模块
|
||||||
'DWBG6A2C_StandLiveInfo': 4,
|
'DWBG6A2C_StandLiveInfo': 4,
|
||||||
@@ -621,6 +635,7 @@ const featureRiskLevels = {
|
|||||||
'DWBG6A2C_CreditDetail': 5,
|
'DWBG6A2C_CreditDetail': 5,
|
||||||
'DWBG6A2C_RentalBehavior': 5,
|
'DWBG6A2C_RentalBehavior': 5,
|
||||||
'DWBG6A2C_RiskSupervision': 8,
|
'DWBG6A2C_RiskSupervision': 8,
|
||||||
|
'DWBG6A2C_CourtRiskInfo': 14,
|
||||||
|
|
||||||
// 贷款风险评估子模块
|
// 贷款风险评估子模块
|
||||||
'CJRZQ5E9F_RiskOverview': 8,
|
'CJRZQ5E9F_RiskOverview': 8,
|
||||||
@@ -833,7 +848,7 @@ watch([reportData, componentRiskScores], () => {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a class="text-blue-500" href="https://beian.miit.gov.cn">
|
<a class="text-blue-500" href="https://beian.miit.gov.cn">
|
||||||
琼ICP备2024048057号-2
|
琼ICP备2024038584号-13
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -862,6 +877,7 @@ watch([reportData, componentRiskScores], () => {
|
|||||||
@apply p-3;
|
@apply p-3;
|
||||||
box-shadow: 0px 0px 24px 0px #3F3F3F0F;
|
box-shadow: 0px 0px 24px 0px #3F3F3F0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 梯形背景图片样式 */
|
/* 梯形背景图片样式 */
|
||||||
.trapezoid-bg-image {
|
.trapezoid-bg-image {
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, nextTick } from "vue";
|
import { ref, computed, nextTick } from "vue";
|
||||||
|
import { showToast } from "vant";
|
||||||
import { useDialogStore } from "@/stores/dialogStore";
|
import { useDialogStore } from "@/stores/dialogStore";
|
||||||
|
import { useAliyunCaptcha } from "@/composables/useAliyunCaptcha";
|
||||||
|
|
||||||
const emit = defineEmits(['bind-success'])
|
const emit = defineEmits(['bind-success'])
|
||||||
|
const { runWithCaptcha } = useAliyunCaptcha();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const dialogStore = useDialogStore();
|
const dialogStore = useDialogStore();
|
||||||
const agentStore = useAgentStore();
|
const agentStore = useAgentStore();
|
||||||
@@ -36,25 +39,26 @@ async function sendVerificationCode() {
|
|||||||
showToast({ message: "请输入有效的手机号" });
|
showToast({ message: "请输入有效的手机号" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { data, error } = await useApiFetch("auth/sendSms")
|
await runWithCaptcha(
|
||||||
.post({ mobile: phoneNumber.value, actionType: "bindMobile" })
|
(captchaVerifyParam) =>
|
||||||
.json();
|
useApiFetch("auth/sendSms")
|
||||||
|
.post({ mobile: phoneNumber.value, actionType: "bindMobile", captchaVerifyParam })
|
||||||
if (data.value && !error.value) {
|
.json(),
|
||||||
if (data.value.code === 200) {
|
(res) => {
|
||||||
showToast({ message: "获取成功" });
|
if (res && res.code === 200) {
|
||||||
startCountdown();
|
showToast({ message: "获取成功" });
|
||||||
// 聚焦到验证码输入框
|
startCountdown();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const verificationCodeInput = document.getElementById('verificationCode');
|
const verificationCodeInput = document.getElementById('verificationCode');
|
||||||
if (verificationCodeInput) {
|
if (verificationCodeInput) {
|
||||||
verificationCodeInput.focus();
|
verificationCodeInput.focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
showToast(data.value.msg);
|
showToast(res?.msg || "发送失败");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function startCountdown() {
|
function startCountdown() {
|
||||||
@@ -155,7 +159,7 @@ function toPrivacyPolicy() {
|
|||||||
<div class="px-8">
|
<div class="px-8">
|
||||||
<div class="mb-8 pt-8 text-left">
|
<div class="mb-8 pt-8 text-left">
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<img class="h-16 w-16 rounded-full shadow" src="/logo.jpg" alt="Logo" />
|
<img class="h-16 w-16 rounded-full shadow" src="/logo.png" alt="Logo" />
|
||||||
<div class="text-3xl mt-4 text-slate-700 font-bold">
|
<div class="text-3xl mt-4 text-slate-700 font-bold">
|
||||||
天远数据
|
天远数据
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -35,7 +35,8 @@
|
|||||||
<input v-model="formData.mobile" id="mobile" type="tel" placeholder="请输入手机号"
|
<input v-model="formData.mobile" id="mobile" type="tel" placeholder="请输入手机号"
|
||||||
class="flex-1 border-none outline-none" @click="handleInputClick" />
|
class="flex-1 border-none outline-none" @click="handleInputClick" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center py-3 border-b border-gray-100">
|
<!-- 小微企业(companyinfo)暂不展示验证码 -->
|
||||||
|
<div v-if="needVerificationCode" class="flex items-center py-3 border-b border-gray-100">
|
||||||
<label for="verificationCode" class="w-20 font-medium text-gray-700">验证码</label>
|
<label for="verificationCode" class="w-20 font-medium text-gray-700">验证码</label>
|
||||||
<input v-model="formData.verificationCode" id="verificationCode" placeholder="请输入验证码"
|
<input v-model="formData.verificationCode" id="verificationCode" placeholder="请输入验证码"
|
||||||
maxlength="6" class="flex-1 border-none outline-none" @click="handleInputClick" />
|
maxlength="6" class="flex-1 border-none outline-none" @click="handleInputClick" />
|
||||||
@@ -265,9 +266,10 @@
|
|||||||
<!-- 支付组件 -->
|
<!-- 支付组件 -->
|
||||||
<Payment v-model="showPayment" :data="featureData" :id="queryId" type="query" @close="showPayment = false" />
|
<Payment v-model="showPayment" :data="featureData" :id="queryId" type="query" @close="showPayment = false" />
|
||||||
<BindPhoneDialog @bind-success="handleBindSuccess" />
|
<BindPhoneDialog @bind-success="handleBindSuccess" />
|
||||||
|
<LoginDialog @login-success="handleLoginSuccess" />
|
||||||
|
|
||||||
<!-- 历史查询按钮 - 仅推广查询显示 -->
|
<!-- 历史查询按钮 - 仅推广查询且已登录时显示 -->
|
||||||
<div v-if="props.type === 'promotion'" @click="toHistory"
|
<div v-if="props.type === 'promotion' && isLoggedIn" @click="toHistory"
|
||||||
class="fixed right-2 top-3/4 px-4 py-2 text-sm bg-primary rounded-xl cursor-pointer text-white font-bold shadow active:bg-blue-500">
|
class="fixed right-2 top-3/4 px-4 py-2 text-sm bg-primary rounded-xl cursor-pointer text-white font-bold shadow active:bg-blue-500">
|
||||||
历史查询
|
历史查询
|
||||||
</div>
|
</div>
|
||||||
@@ -281,10 +283,12 @@ import { useRoute, useRouter } from "vue-router";
|
|||||||
import { useUserStore } from "@/stores/userStore";
|
import { useUserStore } from "@/stores/userStore";
|
||||||
import { useDialogStore } from "@/stores/dialogStore";
|
import { useDialogStore } from "@/stores/dialogStore";
|
||||||
import { useEnv } from "@/composables/useEnv";
|
import { useEnv } from "@/composables/useEnv";
|
||||||
|
import { useAliyunCaptcha } from "@/composables/useAliyunCaptcha";
|
||||||
import { showConfirmDialog } from "vant";
|
import { showConfirmDialog } from "vant";
|
||||||
|
|
||||||
import Payment from "@/components/Payment.vue";
|
import Payment from "@/components/Payment.vue";
|
||||||
import BindPhoneDialog from "@/components/BindPhoneDialog.vue";
|
import BindPhoneDialog from "@/components/BindPhoneDialog.vue";
|
||||||
|
import LoginDialog from "@/components/LoginDialog.vue";
|
||||||
import SectionTitle from "@/components/SectionTitle.vue";
|
import SectionTitle from "@/components/SectionTitle.vue";
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
@@ -349,6 +353,7 @@ const router = useRouter();
|
|||||||
const dialogStore = useDialogStore();
|
const dialogStore = useDialogStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const { isWeChat } = useEnv();
|
const { isWeChat } = useEnv();
|
||||||
|
const { runWithCaptcha } = useAliyunCaptcha();
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const showPayment = ref(false);
|
const showPayment = ref(false);
|
||||||
@@ -378,6 +383,9 @@ const isPhoneNumberValid = computed(() => {
|
|||||||
|
|
||||||
const isIdCardValid = computed(() => /^\d{17}[\dX]$/i.test(formData.idCard));
|
const isIdCardValid = computed(() => /^\d{17}[\dX]$/i.test(formData.idCard));
|
||||||
|
|
||||||
|
// 小微企业(companyinfo)暂不需要验证码
|
||||||
|
const needVerificationCode = computed(() => props.feature !== 'companyinfo');
|
||||||
|
|
||||||
const isLoggedIn = computed(() => userStore.isLoggedIn);
|
const isLoggedIn = computed(() => userStore.isLoggedIn);
|
||||||
|
|
||||||
const buttonText = computed(() => {
|
const buttonText = computed(() => {
|
||||||
@@ -504,19 +512,27 @@ function handleBindSuccess() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理登录成功的回调
|
||||||
|
function handleLoginSuccess() {
|
||||||
|
if (pendingPayment.value) {
|
||||||
|
pendingPayment.value = false;
|
||||||
|
submitRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 处理输入框点击事件
|
// 处理输入框点击事件
|
||||||
const handleInputClick = async () => {
|
const handleInputClick = async () => {
|
||||||
if (!isLoggedIn.value) {
|
if (!isLoggedIn.value) {
|
||||||
// 非微信浏览器环境:未登录用户提示跳转到登录页
|
// 非微信浏览器环境:未登录用户提示打开登录弹窗
|
||||||
if (!isWeChat.value) {
|
if (!isWeChat.value) {
|
||||||
try {
|
try {
|
||||||
await showConfirmDialog({
|
await showConfirmDialog({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
message: '您需要登录后才能进行查询,是否前往登录?',
|
message: '您需要登录后才能进行查询,是否立即登录?',
|
||||||
confirmButtonText: '前往登录',
|
confirmButtonText: '立即登录',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
});
|
});
|
||||||
router.push('/login');
|
dialogStore.openLogin();
|
||||||
} catch {
|
} catch {
|
||||||
// 用户点击取消,什么都不做
|
// 用户点击取消,什么都不做
|
||||||
}
|
}
|
||||||
@@ -532,7 +548,7 @@ const handleInputClick = async () => {
|
|||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
// 非微信浏览器环境:检查登录状态
|
// 非微信浏览器环境:检查登录状态
|
||||||
if (!isWeChat.value && !isLoggedIn.value) {
|
if (!isWeChat.value && !isLoggedIn.value) {
|
||||||
router.push('/login');
|
dialogStore.openLogin();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,12 +572,13 @@ function handleSubmit() {
|
|||||||
(v) => isIdCardValid.value,
|
(v) => isIdCardValid.value,
|
||||||
"请输入有效的身份证号码"
|
"请输入有效的身份证号码"
|
||||||
) ||
|
) ||
|
||||||
!validateField(
|
(needVerificationCode.value &&
|
||||||
"verificationCode",
|
!validateField(
|
||||||
formData.verificationCode,
|
"verificationCode",
|
||||||
(v) => v,
|
formData.verificationCode,
|
||||||
"请输入验证码"
|
(v) => v,
|
||||||
)
|
"请输入验证码"
|
||||||
|
))
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -579,9 +596,11 @@ async function submitRequest() {
|
|||||||
const req = {
|
const req = {
|
||||||
name: formData.name,
|
name: formData.name,
|
||||||
id_card: formData.idCard,
|
id_card: formData.idCard,
|
||||||
mobile: formData.mobile,
|
mobile: formData.mobile
|
||||||
code: formData.verificationCode
|
|
||||||
};
|
};
|
||||||
|
if (needVerificationCode.value) {
|
||||||
|
req.code = formData.verificationCode;
|
||||||
|
}
|
||||||
const reqStr = JSON.stringify(req);
|
const reqStr = JSON.stringify(req);
|
||||||
const encodeData = aesEncrypt(reqStr, "ff83609b2b24fc73196aac3d3dfb874f");
|
const encodeData = aesEncrypt(reqStr, "ff83609b2b24fc73196aac3d3dfb874f");
|
||||||
|
|
||||||
@@ -620,23 +639,26 @@ async function sendVerificationCode() {
|
|||||||
showToast({ message: "请输入有效的手机号" });
|
showToast({ message: "请输入有效的手机号" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
await runWithCaptcha(
|
||||||
const { data, error } = await useApiFetch("/auth/sendSms")
|
(captchaVerifyParam) =>
|
||||||
.post({ mobile: formData.mobile, actionType: "query" })
|
useApiFetch("/auth/sendSms")
|
||||||
.json();
|
.post({ mobile: formData.mobile, actionType: "query", captchaVerifyParam })
|
||||||
|
.json(),
|
||||||
if (!error.value && data.value.code === 200) {
|
(res) => {
|
||||||
showToast({ message: "验证码发送成功", type: "success" });
|
if (res.code === 200) {
|
||||||
startCountdown();
|
showToast({ message: "验证码发送成功", type: "success" });
|
||||||
nextTick(() => {
|
startCountdown();
|
||||||
const verificationCodeInput = document.getElementById('verificationCode');
|
nextTick(() => {
|
||||||
if (verificationCodeInput) {
|
const verificationCodeInput = document.getElementById('verificationCode');
|
||||||
verificationCodeInput.focus();
|
if (verificationCodeInput) {
|
||||||
|
verificationCodeInput.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
showToast({ message: res.msg || "验证码发送失败,请重试" });
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
} else {
|
);
|
||||||
showToast({ message: "验证码发送失败,请重试" });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let timer = null;
|
let timer = null;
|
||||||
@@ -766,4 +788,4 @@ button:active {
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
326
src/components/LoginDialog.vue
Normal file
326
src/components/LoginDialog.vue
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed, nextTick } from 'vue'
|
||||||
|
import { showToast } from 'vant'
|
||||||
|
import ClickCaptcha from '@/components/ClickCaptcha.vue'
|
||||||
|
import { useDialogStore } from '@/stores/dialogStore'
|
||||||
|
import { useUserStore } from '@/stores/userStore'
|
||||||
|
import { useAliyunCaptcha } from "@/composables/useAliyunCaptcha";
|
||||||
|
|
||||||
|
const emit = defineEmits(['login-success'])
|
||||||
|
const dialogStore = useDialogStore()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const phoneNumber = ref('')
|
||||||
|
const verificationCode = ref('')
|
||||||
|
const password = ref('')
|
||||||
|
const isPasswordLogin = ref(false)
|
||||||
|
const isAgreed = ref(false)
|
||||||
|
const isCountingDown = ref(false)
|
||||||
|
const countdown = ref(60)
|
||||||
|
let timer = null
|
||||||
|
|
||||||
|
const { runWithCaptcha } = useAliyunCaptcha();
|
||||||
|
|
||||||
|
// 验证组件状态
|
||||||
|
const showCaptcha = ref(false)
|
||||||
|
const captchaVerified = ref(false)
|
||||||
|
|
||||||
|
// 聚焦状态变量
|
||||||
|
const phoneFocused = ref(false)
|
||||||
|
const codeFocused = ref(false)
|
||||||
|
const passwordFocused = ref(false)
|
||||||
|
|
||||||
|
const isPhoneNumberValid = computed(() => {
|
||||||
|
return /^1[3-9]\d{9}$/.test(phoneNumber.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
const canLogin = computed(() => {
|
||||||
|
if (!isPhoneNumberValid.value) return false
|
||||||
|
if (isPasswordLogin.value) {
|
||||||
|
return password.value.length >= 6
|
||||||
|
} else {
|
||||||
|
return verificationCode.value.length === 6
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
async function sendVerificationCode() {
|
||||||
|
if (isCountingDown.value || !isPhoneNumberValid.value) return
|
||||||
|
if (!isPhoneNumberValid.value) {
|
||||||
|
showToast({ message: "请输入有效的手机号" });
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await runWithCaptcha(
|
||||||
|
(captchaVerifyParam) =>
|
||||||
|
useApiFetch('auth/sendSms')
|
||||||
|
.post({ mobile: phoneNumber.value, actionType: 'login', captchaVerifyParam })
|
||||||
|
.json(),
|
||||||
|
(res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
showToast({ message: "获取成功" });
|
||||||
|
startCountdown();
|
||||||
|
nextTick(() => {
|
||||||
|
const verificationCodeInput = document.getElementById('verificationCode');
|
||||||
|
if (verificationCodeInput) {
|
||||||
|
verificationCodeInput.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
showToast({ message: res.msg || "发送失败" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startCountdown() {
|
||||||
|
isCountingDown.value = true
|
||||||
|
countdown.value = 60
|
||||||
|
timer = setInterval(() => {
|
||||||
|
if (countdown.value > 0) {
|
||||||
|
countdown.value--
|
||||||
|
} else {
|
||||||
|
clearInterval(timer)
|
||||||
|
isCountingDown.value = false
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleLogin() {
|
||||||
|
if (!isPhoneNumberValid.value) {
|
||||||
|
showToast({ message: "请输入有效的手机号" });
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isPasswordLogin.value) {
|
||||||
|
if (password.value.length < 6) {
|
||||||
|
showToast({ message: "密码长度不能小于6位" });
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (verificationCode.value.length !== 6) {
|
||||||
|
showToast({ message: "请输入有效的验证码" });
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isAgreed.value) {
|
||||||
|
showToast({ message: "请先同意用户协议" });
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 显示验证组件
|
||||||
|
showCaptcha.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证成功回调
|
||||||
|
function handleCaptchaSuccess() {
|
||||||
|
captchaVerified.value = true
|
||||||
|
showCaptcha.value = false
|
||||||
|
// 执行实际的登录逻辑
|
||||||
|
performLogin()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证关闭回调
|
||||||
|
function handleCaptchaClose() {
|
||||||
|
showCaptcha.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行实际的登录逻辑
|
||||||
|
async function performLogin() {
|
||||||
|
const { data, error } = await useApiFetch('/user/mobileCodeLogin')
|
||||||
|
.post({ mobile: phoneNumber.value, code: verificationCode.value })
|
||||||
|
.json()
|
||||||
|
|
||||||
|
if (data.value && !error.value) {
|
||||||
|
if (data.value.code === 200) {
|
||||||
|
localStorage.setItem('token', data.value.data.accessToken)
|
||||||
|
localStorage.setItem('refreshAfter', data.value.data.refreshAfter)
|
||||||
|
localStorage.setItem('accessExpire', data.value.data.accessExpire)
|
||||||
|
|
||||||
|
// 更新用户信息
|
||||||
|
await userStore.fetchUserInfo()
|
||||||
|
|
||||||
|
showToast({ message: "登录成功" });
|
||||||
|
closeDialog();
|
||||||
|
emit('login-success');
|
||||||
|
} else {
|
||||||
|
showToast(data.value.msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeDialog() {
|
||||||
|
dialogStore.closeLogin();
|
||||||
|
// 重置表单
|
||||||
|
phoneNumber.value = '';
|
||||||
|
verificationCode.value = '';
|
||||||
|
password.value = '';
|
||||||
|
isPasswordLogin.value = false;
|
||||||
|
isAgreed.value = false;
|
||||||
|
isCountingDown.value = false;
|
||||||
|
countdown.value = 60;
|
||||||
|
if (timer) {
|
||||||
|
clearInterval(timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toUserAgreement() {
|
||||||
|
closeDialog();
|
||||||
|
router.push(`/userAgreement`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toPrivacyPolicy() {
|
||||||
|
closeDialog();
|
||||||
|
router.push(`/privacyPolicy`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<van-popup v-model:show="dialogStore.showLogin" round position="bottom" @close="closeDialog"
|
||||||
|
:style="{ maxHeight: '90vh' }">
|
||||||
|
<div class="login-dialog">
|
||||||
|
<div class="title-bar">
|
||||||
|
<div class="text-base sm:text-lg font-bold">登录</div>
|
||||||
|
<van-icon name="cross" class="close-icon" @click="closeDialog" />
|
||||||
|
</div>
|
||||||
|
<div class="px-8">
|
||||||
|
<div class="mb-8 pt-8 text-left">
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<img class="h-16 w-16 rounded-full shadow" src="/logo.png" alt="Logo" />
|
||||||
|
<div class="text-3xl mt-4 text-slate-700 font-bold">
|
||||||
|
天远数据
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-5">
|
||||||
|
<!-- 手机号输入 -->
|
||||||
|
<div :class="[
|
||||||
|
'input-container bg-blue-300/20',
|
||||||
|
phoneFocused ? 'focused' : '',
|
||||||
|
]">
|
||||||
|
<input v-model="phoneNumber" class="input-field" type="tel" placeholder="请输入手机号"
|
||||||
|
maxlength="11" @focus="phoneFocused = true" @blur="phoneFocused = false" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 验证码输入 -->
|
||||||
|
<div v-if="!isPasswordLogin" class="flex items-center justify-between">
|
||||||
|
<div :class="[
|
||||||
|
'input-container bg-blue-300/20',
|
||||||
|
codeFocused ? 'focused' : '',
|
||||||
|
]">
|
||||||
|
<input v-model="verificationCode" id="verificationCode" class="input-field"
|
||||||
|
placeholder="请输入验证码" maxlength="6" @focus="codeFocused = true"
|
||||||
|
@blur="codeFocused = false" />
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="ml-2 px-4 py-2 text-sm font-bold flex-shrink-0 rounded-lg transition duration-300"
|
||||||
|
:class="isCountingDown || !isPhoneNumberValid
|
||||||
|
? 'cursor-not-allowed bg-gray-300 text-gray-500'
|
||||||
|
: 'bg-blue-500 text-white hover:bg-blue-600'
|
||||||
|
" @click="sendVerificationCode">
|
||||||
|
{{
|
||||||
|
isCountingDown
|
||||||
|
? `${countdown}s重新获取`
|
||||||
|
: "获取验证码"
|
||||||
|
}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 密码输入 -->
|
||||||
|
<div v-else :class="[
|
||||||
|
'input-container bg-blue-300/20',
|
||||||
|
passwordFocused ? 'focused' : '',
|
||||||
|
]">
|
||||||
|
<input v-model="password" class="input-field" type="password" placeholder="请输入密码"
|
||||||
|
@focus="passwordFocused = true" @blur="passwordFocused = false" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 登录方式切换 -->
|
||||||
|
<div class="flex justify-end items-center">
|
||||||
|
<div class="text-sm text-blue-500 cursor-pointer" @click="isPasswordLogin = !isPasswordLogin">
|
||||||
|
{{ isPasswordLogin ? '验证码登录' : '密码登录' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 协议同意框 -->
|
||||||
|
<div class="flex items-start space-x-2">
|
||||||
|
<input type="checkbox" v-model="isAgreed" class="mt-1" />
|
||||||
|
<span class="text-xs text-gray-400 leading-tight">
|
||||||
|
登录即代表您已阅读并同意
|
||||||
|
<a class="cursor-pointer text-blue-400" @click="toUserAgreement">
|
||||||
|
《用户协议》
|
||||||
|
</a>
|
||||||
|
和
|
||||||
|
<a class="cursor-pointer text-blue-400" @click="toPrivacyPolicy">
|
||||||
|
《隐私政策》
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="mt-10 w-full py-3 text-lg font-bold text-white bg-blue-500 rounded-full transition duration-300"
|
||||||
|
:class="{ 'opacity-50 cursor-not-allowed': !canLogin }" @click="handleLogin">
|
||||||
|
登 录
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-popup>
|
||||||
|
|
||||||
|
<!-- 点击验证组件 -->
|
||||||
|
<ClickCaptcha :visible="showCaptcha" @success="handleCaptchaSuccess" @close="handleCaptchaClose" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.login-dialog {
|
||||||
|
background: url("@/assets/images/login_bg.png") no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #666;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container {
|
||||||
|
border: 2px solid rgba(125, 211, 252, 0);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
transition: all 0.3s;
|
||||||
|
height: 3rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container.focused {
|
||||||
|
border: 2px solid rgba(59, 130, 246, 0.5);
|
||||||
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-field {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 1rem;
|
||||||
|
color: #333;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-field::placeholder {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-checkbox {
|
||||||
|
accent-color: #3b82f6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
107
src/components/MaintenanceDialog.vue
Normal file
107
src/components/MaintenanceDialog.vue
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
|
||||||
|
const showMaintenance = ref(false);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 每次访问网址时显示全屏维护遮罩,遮挡所有页面
|
||||||
|
showMaintenance.value = true;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<!-- 全屏维护遮罩:固定覆盖整个视口,置于最顶层,阻挡所有页面操作 -->
|
||||||
|
<Teleport to="body">
|
||||||
|
<Transition name="maintenance-fade">
|
||||||
|
<div
|
||||||
|
v-show="showMaintenance"
|
||||||
|
class="maintenance-overlay"
|
||||||
|
aria-hidden="false"
|
||||||
|
>
|
||||||
|
<div class="maintenance-card">
|
||||||
|
<div class="dialog-header">
|
||||||
|
<div class="title">系统升级维护公告</div>
|
||||||
|
</div>
|
||||||
|
<div class="dialog-content">
|
||||||
|
<p class="content-text">
|
||||||
|
为进一步提升系统稳定性与服务效能,我单位正在进行后台升级改造。
|
||||||
|
</p>
|
||||||
|
<p class="content-text">
|
||||||
|
维护期间,相关功能模块将暂时无法使用。 由此给您带来的不便,敬请谅解。感谢您一直以来的理解与支持!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<span class="ack-text">感谢您的理解与支持</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.maintenance-overlay {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 99999;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(0, 0, 0, 0.85);
|
||||||
|
padding: 24px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maintenance-card {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 520px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-header {
|
||||||
|
padding: 24px 24px 16px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-content {
|
||||||
|
padding: 24px;
|
||||||
|
min-height: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-text {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.8;
|
||||||
|
color: #555;
|
||||||
|
margin: 12px 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
padding: 20px 24px 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ack-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maintenance-fade-enter-active,
|
||||||
|
.maintenance-fade-leave-active {
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
.maintenance-fade-enter-from,
|
||||||
|
.maintenance-fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
<!-- 支付宝支付 -->
|
<!-- 支付宝支付 -->
|
||||||
<van-cell
|
<van-cell
|
||||||
v-else
|
v-if="!isWeChat"
|
||||||
title="支付宝支付"
|
title="支付宝支付"
|
||||||
clickable
|
clickable
|
||||||
@click="selectedPaymentMethod = 'alipay'"
|
@click="selectedPaymentMethod = 'alipay'"
|
||||||
@@ -80,6 +80,29 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
|
|
||||||
|
<!-- 开发环境测试支付(仅开发环境显示,不跳转支付宝/微信,生成空报告) -->
|
||||||
|
<van-cell
|
||||||
|
v-if="isDev"
|
||||||
|
title="开发环境测试支付"
|
||||||
|
clickable
|
||||||
|
@click="selectedPaymentMethod = 'test'"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<van-icon
|
||||||
|
size="24"
|
||||||
|
name="description"
|
||||||
|
color="#ff976a"
|
||||||
|
class="mr-2"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #right-icon>
|
||||||
|
<van-radio
|
||||||
|
v-model="selectedPaymentMethod"
|
||||||
|
name="test"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</van-cell>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
</div>
|
</div>
|
||||||
<!-- 确认按钮 -->
|
<!-- 确认按钮 -->
|
||||||
@@ -92,8 +115,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, defineProps } from "vue";
|
import { ref, defineProps, watch } from "vue";
|
||||||
const { isWeChat } = useEnv();
|
const { isWeChat } = useEnv();
|
||||||
|
const isDev = import.meta.env.DEV;
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
@@ -111,62 +135,92 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
const show = defineModel();
|
const show = defineModel();
|
||||||
const selectedPaymentMethod = ref(isWeChat.value ? "wechat" : "alipay");
|
const selectedPaymentMethod = ref(isWeChat.value ? "wechat" : "alipay");
|
||||||
onMounted(() => {
|
|
||||||
if (isWeChat.value) {
|
function setDefaultPaymentMethod() {
|
||||||
selectedPaymentMethod.value = "wechat";
|
selectedPaymentMethod.value = isWeChat.value ? "wechat" : "alipay";
|
||||||
} else {
|
}
|
||||||
selectedPaymentMethod.value = "alipay";
|
onMounted(setDefaultPaymentMethod);
|
||||||
}
|
|
||||||
|
// 每次打开弹窗时重置为支付宝/微信,避免上一次选的「开发环境测试支付」被沿用导致误走自动 paid
|
||||||
|
watch(show, (v) => {
|
||||||
|
if (v) setDefaultPaymentMethod();
|
||||||
});
|
});
|
||||||
|
|
||||||
const orderNo = ref("");
|
const orderNo = ref("");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const discountPrice = ref(false); // 是否应用折扣
|
const discountPrice = ref(false); // 是否应用折扣
|
||||||
onMounted(() => {
|
|
||||||
if (isWeChat.value) {
|
|
||||||
selectedPaymentMethod.value = "wechat";
|
|
||||||
} else {
|
|
||||||
selectedPaymentMethod.value = "alipay";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function getPayment() {
|
async function getPayment() {
|
||||||
const { data, error } = await useApiFetch("/pay/payment")
|
showConfirmDialog({
|
||||||
.post({
|
title: "重要安全声明",
|
||||||
id: props.id,
|
message: `为保障您的个人信息与资金安全,请您务必知悉以下事项:
|
||||||
pay_method: selectedPaymentMethod.value,
|
|
||||||
pay_type: props.type,
|
|
||||||
})
|
|
||||||
.json();
|
|
||||||
|
|
||||||
if (data.value && !error.value) {
|
关于平台业务:本平台官方服务仅限于大数据报告查询,不涉及也从未开展"央行征信修复"、"贷款办理"或"征信洗白"等相关业务。请注意,本平台出具的报告仅供决策参考,不可作为任何官方征信凭证或贷款依据。
|
||||||
if (selectedPaymentMethod.value === "alipay") {
|
|
||||||
orderNo.value = data.value.data.order_no;
|
关于诈骗警示:任何自称与本平台合作,或以"内部渠道"、"百分百包下款"、"修复征信"等为由,诱导您进行支付的行为,均属欺诈。请您切勿相信,谨慎对待任何支付要求。
|
||||||
// 存储订单ID以便支付宝返回时获取
|
|
||||||
const prepayUrl = data.value.data.prepay_id;
|
关于安全提示:请您时刻保持警惕,妥善保管个人敏感信息。如遇任何索款要求或可疑承诺,请务必首先通过我平台官方公布的联系方式进行核实,切勿轻信他人。`,
|
||||||
const paymentForm = document.createElement("form");
|
})
|
||||||
paymentForm.method = "POST";
|
.then(async () => {
|
||||||
paymentForm.action = prepayUrl;
|
const { data, error } = await useApiFetch("/pay/payment")
|
||||||
paymentForm.style.display = "none";
|
.post({
|
||||||
document.body.appendChild(paymentForm);
|
id: props.id,
|
||||||
paymentForm.submit();
|
pay_method: selectedPaymentMethod.value,
|
||||||
} else {
|
pay_type: props.type,
|
||||||
const payload = data.value.data.prepay_data;
|
})
|
||||||
WeixinJSBridge.invoke(
|
.json();
|
||||||
"getBrandWCPayRequest",
|
|
||||||
payload,
|
if (data.value && !error.value) {
|
||||||
function (res) {
|
const prepayId = data.value.data.prepay_id;
|
||||||
if (res.err_msg == "get_brand_wcpay_request:ok") {
|
const orderNoFromResp = data.value.data.order_no;
|
||||||
// 支付成功,直接跳转到结果页面
|
|
||||||
router.push({
|
// 开发环境测试支付:仅当用户选择「开发环境测试支付」时后端才返回 test_payment_success
|
||||||
path: "/payment/result",
|
// 若选择支付宝/微信却收到此值,说明后端异常,不跳转、直接报错
|
||||||
query: { orderNo: data.value.data.order_no },
|
if (prepayId === "test_payment_success") {
|
||||||
});
|
if (selectedPaymentMethod.value === "alipay" || selectedPaymentMethod.value === "wechat") {
|
||||||
|
showToast({ message: "支付参数异常,请重试", type: "fail" });
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
show.value = false;
|
||||||
|
router.push({
|
||||||
|
path: "/payment/result",
|
||||||
|
query: { orderNo: orderNoFromResp },
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
if (selectedPaymentMethod.value === "alipay") {
|
||||||
}
|
orderNo.value = orderNoFromResp;
|
||||||
show.value = false;
|
// 存储订单ID以便支付宝返回时获取
|
||||||
|
const prepayUrl = prepayId;
|
||||||
|
const paymentForm = document.createElement("form");
|
||||||
|
paymentForm.method = "POST";
|
||||||
|
paymentForm.action = prepayUrl;
|
||||||
|
paymentForm.style.display = "none";
|
||||||
|
document.body.appendChild(paymentForm);
|
||||||
|
paymentForm.submit();
|
||||||
|
} else {
|
||||||
|
const payload = data.value.data.prepay_data;
|
||||||
|
WeixinJSBridge.invoke(
|
||||||
|
"getBrandWCPayRequest",
|
||||||
|
payload,
|
||||||
|
function (res) {
|
||||||
|
if (res.err_msg == "get_brand_wcpay_request:ok") {
|
||||||
|
// 支付成功,直接跳转到结果页面
|
||||||
|
router.push({
|
||||||
|
path: "/payment/result",
|
||||||
|
query: { orderNo: orderNoFromResp },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
show.value = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
return;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import { useDialogStore } from "@/stores/dialogStore";
|
import { useDialogStore } from "@/stores/dialogStore";
|
||||||
|
import { showToast } from "vant";
|
||||||
|
import { useAliyunCaptcha } from "@/composables/useAliyunCaptcha";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const dialogStore = useDialogStore();
|
const dialogStore = useDialogStore();
|
||||||
const agentStore = useAgentStore();
|
const agentStore = useAgentStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
import { showToast } from "vant";
|
const { runWithCaptcha } = useAliyunCaptcha();
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const realName = ref("");
|
const realName = ref("");
|
||||||
const idCard = ref("");
|
const idCard = ref("");
|
||||||
@@ -47,25 +50,27 @@ const canSubmit = computed(() => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 发送验证码
|
// 发送验证码(先通过图形验证滑块再请求接口)
|
||||||
async function sendVerificationCode() {
|
async function sendVerificationCode() {
|
||||||
if (isCountingDown.value || !isPhoneNumberValid.value) return;
|
if (isCountingDown.value || !isPhoneNumberValid.value) return;
|
||||||
if (!isPhoneNumberValid.value) {
|
if (!isPhoneNumberValid.value) {
|
||||||
showToast({ message: "请输入有效的手机号" });
|
showToast({ message: "请输入有效的手机号" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { data, error } = await useApiFetch("auth/sendSms")
|
await runWithCaptcha(
|
||||||
.post({ mobile: phoneNumber.value, actionType: "realName" })
|
(captchaVerifyParam) =>
|
||||||
.json();
|
useApiFetch("auth/sendSms")
|
||||||
|
.post({ mobile: phoneNumber.value, actionType: "realName", captchaVerifyParam })
|
||||||
if (data.value && !error.value) {
|
.json(),
|
||||||
if (data.value.code === 200) {
|
(res) => {
|
||||||
showToast({ message: "获取成功" });
|
if (res && res.code === 200) {
|
||||||
startCountdown();
|
showToast({ message: "获取成功" });
|
||||||
} else {
|
startCountdown();
|
||||||
showToast(data.value.msg);
|
} else {
|
||||||
|
showToast(res?.msg || "发送失败");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function startCountdown() {
|
function startCountdown() {
|
||||||
|
|||||||
@@ -10,23 +10,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue';
|
import { useEnv } from '@/composables/useEnv';
|
||||||
|
|
||||||
// 定义一个响应式变量,表示是否在微信环境
|
// 使用全局的微信环境检测,与 App.vue 保持一致ss
|
||||||
const isWeChat = ref(false);
|
const { isWeChat } = useEnv();
|
||||||
|
|
||||||
// 检查是否为微信环境
|
|
||||||
const checkIfWeChat = () => {
|
|
||||||
const userAgent = navigator.userAgent.toLowerCase();
|
|
||||||
isWeChat.value = /micromessenger/.test(userAgent);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 在组件挂载后检查环境
|
|
||||||
onMounted(() => {
|
|
||||||
checkIfWeChat();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* 遮罩层样式 */
|
/* 遮罩层样式 */
|
||||||
.wechat-overlay {
|
.wechat-overlay {
|
||||||
|
|||||||
153
src/composables/useAliyunCaptcha.js
Normal file
153
src/composables/useAliyunCaptcha.js
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
import { showToast, showLoadingToast, closeToast } from "vant";
|
||||||
|
import useApiFetch from "@/composables/useApiFetch";
|
||||||
|
|
||||||
|
const ALIYUN_CAPTCHA_SCENE_ID = "wynt39to";
|
||||||
|
const ENABLE_ENCRYPTED = false;
|
||||||
|
|
||||||
|
let captchaInitialised = false;
|
||||||
|
let captchaReadyPromise = null;
|
||||||
|
let captchaReadyResolve = null;
|
||||||
|
|
||||||
|
async function ensureCaptchaInit() {
|
||||||
|
if (captchaInitialised || typeof window === "undefined") return;
|
||||||
|
if (typeof window.initAliyunCaptcha !== "function") return;
|
||||||
|
|
||||||
|
captchaInitialised = true;
|
||||||
|
window.captcha = null;
|
||||||
|
window.__lastBizResponse = null;
|
||||||
|
window.__onCaptchaBizSuccess = null;
|
||||||
|
captchaReadyPromise = new Promise((resolve) => {
|
||||||
|
captchaReadyResolve = resolve;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!ENABLE_ENCRYPTED) {
|
||||||
|
window.initAliyunCaptcha({
|
||||||
|
SceneId: ALIYUN_CAPTCHA_SCENE_ID,
|
||||||
|
mode: "popup",
|
||||||
|
element: "#captcha-element",
|
||||||
|
getInstance(instance) {
|
||||||
|
window.captcha = instance;
|
||||||
|
if (typeof captchaReadyResolve === "function") {
|
||||||
|
captchaReadyResolve();
|
||||||
|
captchaReadyResolve = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
captchaVerifyCallback(param) {
|
||||||
|
return typeof window.__captchaVerifyCallback === "function"
|
||||||
|
? window.__captchaVerifyCallback(param)
|
||||||
|
: Promise.resolve({
|
||||||
|
captchaResult: false,
|
||||||
|
bizResult: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onBizResultCallback(bizResult) {
|
||||||
|
if (typeof window.__onBizResultCallback === "function") {
|
||||||
|
window.__onBizResultCallback(bizResult);
|
||||||
|
}
|
||||||
|
window.__lastBizResponse = null;
|
||||||
|
window.__onCaptchaBizSuccess = null;
|
||||||
|
},
|
||||||
|
slideStyle: { width: 360, height: 40 },
|
||||||
|
language: "cn",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data, error } = await useApiFetch("/captcha/encryptedSceneId").post().json();
|
||||||
|
const resp = data?.value;
|
||||||
|
const encryptedSceneId = resp?.data?.encryptedSceneId;
|
||||||
|
if (error?.value || !encryptedSceneId) {
|
||||||
|
showToast({ message: "获取验证码参数失败,请稍后重试" });
|
||||||
|
captchaInitialised = false;
|
||||||
|
captchaReadyPromise = null;
|
||||||
|
captchaReadyResolve = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.initAliyunCaptcha({
|
||||||
|
SceneId: ALIYUN_CAPTCHA_SCENE_ID,
|
||||||
|
EncryptedSceneId: encryptedSceneId,
|
||||||
|
mode: "popup",
|
||||||
|
element: "#captcha-element",
|
||||||
|
getInstance(instance) {
|
||||||
|
window.captcha = instance;
|
||||||
|
if (typeof captchaReadyResolve === "function") {
|
||||||
|
captchaReadyResolve();
|
||||||
|
captchaReadyResolve = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
captchaVerifyCallback(param) {
|
||||||
|
return typeof window.__captchaVerifyCallback === "function"
|
||||||
|
? window.__captchaVerifyCallback(param)
|
||||||
|
: Promise.resolve({ captchaResult: false, bizResult: false });
|
||||||
|
},
|
||||||
|
onBizResultCallback(bizResult) {
|
||||||
|
if (typeof window.__onBizResultCallback === "function") {
|
||||||
|
window.__onBizResultCallback(bizResult);
|
||||||
|
}
|
||||||
|
window.__lastBizResponse = null;
|
||||||
|
window.__onCaptchaBizSuccess = null;
|
||||||
|
},
|
||||||
|
slideStyle: { width: 360, height: 40 },
|
||||||
|
language: "cn",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useAliyunCaptcha() {
|
||||||
|
async function runWithCaptcha(bizVerify, onSuccess) {
|
||||||
|
if (typeof window === "undefined") {
|
||||||
|
showToast({ message: "验证码仅支持浏览器环境" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loading = showLoadingToast({
|
||||||
|
message: "安全验证加载中...",
|
||||||
|
forbidClick: true,
|
||||||
|
duration: 0,
|
||||||
|
loadingType: "spinner",
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.__captchaVerifyCallback = async (captchaVerifyParam) => {
|
||||||
|
window.__lastBizResponse = null;
|
||||||
|
const { data, error } = await bizVerify(captchaVerifyParam);
|
||||||
|
const result = data?.value ?? data;
|
||||||
|
if (error?.value || !result) {
|
||||||
|
return { captchaResult: false, bizResult: false };
|
||||||
|
}
|
||||||
|
window.__lastBizResponse = result;
|
||||||
|
const captchaOk = result.captchaVerifyResult !== false;
|
||||||
|
const bizOk = result.code === 200;
|
||||||
|
return { captchaResult: captchaOk, bizResult: bizOk };
|
||||||
|
};
|
||||||
|
|
||||||
|
window.__onBizResultCallback = (bizResult) => {
|
||||||
|
if (
|
||||||
|
bizResult === true &&
|
||||||
|
window.__lastBizResponse &&
|
||||||
|
typeof window.__onCaptchaBizSuccess === "function"
|
||||||
|
) {
|
||||||
|
window.__onCaptchaBizSuccess(window.__lastBizResponse);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await ensureCaptchaInit();
|
||||||
|
|
||||||
|
if (captchaReadyPromise) {
|
||||||
|
await captchaReadyPromise;
|
||||||
|
captchaReadyPromise = null;
|
||||||
|
}
|
||||||
|
if (!window.captcha) {
|
||||||
|
showToast({ message: "验证码未加载,请刷新页面重试" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.__onCaptchaBizSuccess = onSuccess;
|
||||||
|
window.captcha.show();
|
||||||
|
} finally {
|
||||||
|
closeToast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { runWithCaptcha };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useAliyunCaptcha;
|
||||||
@@ -51,22 +51,34 @@ const useApiFetch = createFetch({
|
|||||||
|
|
||||||
if (data.code !== 200) {
|
if (data.code !== 200) {
|
||||||
if (data.code === 100009) {
|
if (data.code === 100009) {
|
||||||
// 改进的存储管理
|
// 用户不存在:清除并刷新
|
||||||
localStorage.removeItem('token')
|
localStorage.removeItem('token')
|
||||||
localStorage.removeItem('refreshAfter')
|
localStorage.removeItem('refreshAfter')
|
||||||
localStorage.removeItem('accessExpire')
|
localStorage.removeItem('accessExpire')
|
||||||
localStorage.removeItem('userInfo')
|
localStorage.removeItem('userInfo')
|
||||||
localStorage.removeItem('agentInfo')
|
localStorage.removeItem('agentInfo')
|
||||||
|
|
||||||
// 重置状态
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const agentStore = useAgentStore();
|
const agentStore = useAgentStore();
|
||||||
userStore.resetUser()
|
userStore.resetUser()
|
||||||
agentStore.resetAgent()
|
agentStore.resetAgent()
|
||||||
location.reload()
|
location.reload()
|
||||||
|
|
||||||
}
|
}
|
||||||
if (data.code !== 200002 && data.code !== 200003 && data.code !== 200004 && data.code !== 100009) {
|
if (data.code === 100011) {
|
||||||
|
// 账号已被封禁:提示并跳转登录
|
||||||
|
showToast({ message: data.msg || "账号已被封禁" });
|
||||||
|
localStorage.removeItem('token')
|
||||||
|
localStorage.removeItem('refreshAfter')
|
||||||
|
localStorage.removeItem('accessExpire')
|
||||||
|
localStorage.removeItem('userInfo')
|
||||||
|
localStorage.removeItem('agentInfo')
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const agentStore = useAgentStore();
|
||||||
|
userStore.resetUser()
|
||||||
|
agentStore.resetAgent()
|
||||||
|
router.replace("/login");
|
||||||
|
}
|
||||||
|
if (data.code !== 200002 && data.code !== 200003 && data.code !== 200004 && data.code !== 100009 && data.code !== 100011) {
|
||||||
showToast({ message: data.msg });
|
showToast({ message: data.msg });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,12 +87,23 @@ const useApiFetch = createFetch({
|
|||||||
async onFetchError({ error, response }) {
|
async onFetchError({ error, response }) {
|
||||||
console.log("error", error);
|
console.log("error", error);
|
||||||
closeToast();
|
closeToast();
|
||||||
if (response.status === 401) {
|
if (response?.status === 401) {
|
||||||
// 清除本地存储的 token
|
|
||||||
localStorage.removeItem("token");
|
localStorage.removeItem("token");
|
||||||
localStorage.removeItem('refreshAfter')
|
localStorage.removeItem('refreshAfter')
|
||||||
localStorage.removeItem('accessExpire')
|
localStorage.removeItem('accessExpire')
|
||||||
// 跳转到登录页
|
router.replace("/login");
|
||||||
|
} else if (response?.status === 403) {
|
||||||
|
// 账号已被封禁
|
||||||
|
showToast({ message: "账号已被封禁" });
|
||||||
|
localStorage.removeItem("token");
|
||||||
|
localStorage.removeItem('refreshAfter')
|
||||||
|
localStorage.removeItem('accessExpire')
|
||||||
|
localStorage.removeItem('userInfo')
|
||||||
|
localStorage.removeItem('agentInfo')
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const agentStore = useAgentStore();
|
||||||
|
userStore.resetUser()
|
||||||
|
agentStore.resetAgent()
|
||||||
router.replace("/login");
|
router.replace("/login");
|
||||||
} else {
|
} else {
|
||||||
if (typeof error === "string") {
|
if (typeof error === "string") {
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ export function useSEO() {
|
|||||||
|
|
||||||
// 默认SEO信息
|
// 默认SEO信息
|
||||||
const defaultSEO = {
|
const defaultSEO = {
|
||||||
title: '天远数据|大数据风险报告查询与代理平台,支持个人和企业多场景风控应用',
|
title: '天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台',
|
||||||
description: '天远数据,专业大数据风险报告查询与代理平台,支持个人信用查询、小微企业风控、贷前风险背调等多场景报告应用,免费开通代理权限,助力高效识别信用与风险。',
|
description: '天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。',
|
||||||
keywords: '大数据风险报告查询、大数据风险评估、大数据分析报告、个人大数据风险查询、小微企业风险、贷前风险背调、代理管理平台、免费开通代理、风险管控平台、信用风险分析、企业风险报告、贷前信用审核、失信人名单查询、被执行人信息、信用黑名单查询',
|
keywords: '天远数据,职场背调,风险核验报告,家政背景核验,第三方背调,企业风控服务,数据报告分销',
|
||||||
url: 'https://www.zhinengcha.cn'
|
url: 'https://www.tianyuandb.com'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页面SEO配置
|
// 页面SEO配置
|
||||||
@@ -131,7 +131,7 @@ export function useSEO() {
|
|||||||
"mainEntity": {
|
"mainEntity": {
|
||||||
"@type": "Organization",
|
"@type": "Organization",
|
||||||
"name": "天远数据",
|
"name": "天远数据",
|
||||||
"url": "https://www.zhinengcha.cn/",
|
"url": "https://www.tianyuandb.com/",
|
||||||
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
"description": "专业大数据风险报告查询与代理平台,支持个人和企业多场景风控应用"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,19 +146,61 @@ export function useSEO() {
|
|||||||
const updateSEOByRoute = () => {
|
const updateSEOByRoute = () => {
|
||||||
const routeConfigs = {
|
const routeConfigs = {
|
||||||
'/': {
|
'/': {
|
||||||
title: '天远数据|大数据风险报告查询与代理平台,支持个人和企业多场景风控应用',
|
title: '天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台',
|
||||||
description: '天远数据,专业大数据风险报告查询与代理平台,支持个人信用查询、小微企业风控、贷前风险背调等多场景报告应用,免费开通代理权限,助力高效识别信用与风险。',
|
description: '天远数据提供低成本的风控系统搭建服务。一键开通独立代理后台,支持自定义品牌与报告价格。平台基于公开合法数据,支持一键生成综合素质报告。诚邀行业合作伙伴,共享数字化风控红利,助力流量合规变现。',
|
||||||
keywords: '大数据风险报告查询、大数据风险评估、大数据分析报告、个人大数据风险查询、小微企业风险、贷前风险背调、代理管理平台、免费开通代理、风险管控平台、信用风险分析、企业风险报告、贷前信用审核、失信人名单查询、被执行人信息、信用黑名单查询'
|
keywords: '天远数据,职场背调,风险核验报告,家政背景核验,第三方背调,企业风控服务,数据报告分销'
|
||||||
},
|
},
|
||||||
|
'/historyQuery': {
|
||||||
|
title: '我的报告_历史查询记录_天远数据',
|
||||||
|
description: '天远数据用户个人中心,查看及下载历史查询报告。',
|
||||||
|
keywords: '我的报告,历史记录,天远数据'
|
||||||
|
},
|
||||||
|
// 个人查询
|
||||||
|
'/inquire/personalData': {
|
||||||
|
title: '个人综合风险报告_个人履约评分_多维数据检测_天远数据',
|
||||||
|
description: '天远数据提供个人全维信用画像扫描。一键检测司法涉诉记录、历史履约情况、号码状态异常检测及个人消费等级。数据同步权威行业系统,采用银行级加密技术,保障信息安全,助您全面了解自身信用状况。',
|
||||||
|
keywords: '个人风险评估,信用状况评估,综合履约能力,司法风险自查,风险标签检测'
|
||||||
|
},
|
||||||
|
// 企业查询
|
||||||
|
'/inquire/companyinfo': {
|
||||||
|
title: '企业信用风险评估_工商经营异常与司法诉讼核查_天远数据',
|
||||||
|
description: '天远数据提供全维度的企业商业画像。基于官方公示数据,核验目标企业的工商变更、经营异常名录、行政处罚、投融资背景及关联风险。深度评估商业履约能力,透视合作方真实状况,规避合同陷阱。',
|
||||||
|
keywords: '企业信用画像,公司经营风险,工商异常名录,企业履约评估,商业背景核验'
|
||||||
|
},
|
||||||
|
// 贷前风险
|
||||||
|
'/inquire/preloanbackgroundcheck': {
|
||||||
|
title: '综合履约评分检测_多平台履约记录分析_个人财务履约报告_天远数据',
|
||||||
|
description: '天远数据提供专业的个人履约健康度体检服务。基于多维大数据分析,检测您的综合评分波动、历史履约记录及潜在的风险标签。本服务旨在帮助用户优化个人数据画像,提升信用管理意识,不提供任何信贷金融服务。',
|
||||||
|
keywords: '综合评分检测,多重履约压力分析,履约能力评估,综合评分优化,个人数据画像'
|
||||||
|
},
|
||||||
|
// 婚恋风险
|
||||||
|
'/inquire/marriage': {
|
||||||
|
title: '婚恋对象背景了解_司法诉讼与不良记录筛查_婚前风险评估_天远数据',
|
||||||
|
description: '天远数据提供专业的婚恋风险评估工具。基于合法的公开司法数据,深度排查法律诉讼记录、失信被执行信息及潜在的履约风险。数据来源合规,仅供个人防范参考,拒绝隐私泄露,为幸福保驾护航。',
|
||||||
|
keywords: '婚恋背景核验,婚前风险了解,司法记录核验,个人履约风险,背景核实'
|
||||||
|
},
|
||||||
|
// 入职背调
|
||||||
|
'/inquire/backgroundcheck': {
|
||||||
|
title: '入职背景核验_候选人履历核验_职场信用与竞业排查_天远数据',
|
||||||
|
description: '天远数据职场风险报告助力企业构建防御体系。基于司法级大数据,一键筛查候选人司法涉诉记录、学历信息、商业利益冲突、历史违约记录及不良社会风险。官方数据,客观预警入职风险,辅助HR高效决策。',
|
||||||
|
keywords: '入职风险评估,候选人背景核验,简历真伪辨别,竞业限制核验,职场信用报告,员工风险预警'
|
||||||
|
},
|
||||||
|
// 家政风险
|
||||||
|
'/inquire/homeservice': {
|
||||||
|
title: '家政人员背景核实_保姆月嫂司法风险筛查_用工安全评估_天远数据',
|
||||||
|
description: '天远数据家政风险报告,为家庭用人安全把关。通过合法大数据,快速筛查家政人员的司法诉讼、失信被执行记录及社会不良风险标签。有效识别潜在隐患,预防雇佣纠纷,让您找保姆、请月嫂更放心。',
|
||||||
|
keywords: '保姆背景核验,月嫂风险筛查,家政人员核验,育儿嫂背景核实,雇佣风险防范'
|
||||||
|
},
|
||||||
|
|
||||||
'/agent': {
|
'/agent': {
|
||||||
title: '天远数据代理 - 免费开通代理权限 | 大数据风险报告代理',
|
title: '天远数据代理 - 免费开通代理权限 | 大数据风险报告代理',
|
||||||
description: '天远数据代理平台,免费开通代理权限,享受大数据风险报告查询服务代理收益。专业的大数据风险报告、婚姻查询、个人信用评估等服务的代理合作。',
|
description: '天远数据代理平台,免费开通代理权限,享受大数据风险报告查询服务代理收益。专业的大数据风险报告、婚姻查询、个人信用评估等服务的代理合作。',
|
||||||
keywords: '天远数据代理, 免费代理, 大数据风险报告代理, 代理权限, 代理收益'
|
keywords: '天远数据代理, 免费代理, 大数据风险报告代理, 代理权限, 代理收益'
|
||||||
},
|
},
|
||||||
'/help': {
|
'/help': {
|
||||||
title: '帮助中心 - 天远数据使用指南 | 常见问题解答',
|
title: '天远数据帮助中心_代理操作指南_推广收益计算常见问题',
|
||||||
description: '天远数据帮助中心,提供详细的使用指南、常见问题解答、操作教程等,帮助用户更好地使用大数据风险报告查询服务。',
|
description: '天远数据帮助中心提供全方位的代理操作指引。包含如何成为代理、推广报告生成教程、收益与成本计算规则及推广效率提升方案。',
|
||||||
keywords: '天远数据帮助, 使用指南, 常见问题, 操作教程, 客服支持'
|
keywords: '天远数据教程,代理新手指南,推广收益计算,报告推广'
|
||||||
},
|
},
|
||||||
'/help/guide': {
|
'/help/guide': {
|
||||||
title: '使用指南 - 天远数据操作教程 | 功能说明',
|
title: '使用指南 - 天远数据操作教程 | 功能说明',
|
||||||
@@ -174,15 +216,25 @@ export function useSEO() {
|
|||||||
title: '客服中心 - 天远数据在线客服 | 技术支持',
|
title: '客服中心 - 天远数据在线客服 | 技术支持',
|
||||||
description: '天远数据客服中心,提供在线客服支持、技术咨询、问题反馈等服务,确保用户获得及时有效的帮助。',
|
description: '天远数据客服中心,提供在线客服支持、技术咨询、问题反馈等服务,确保用户获得及时有效的帮助。',
|
||||||
keywords: '客服中心, 在线客服, 技术支持, 问题反馈, 天远数据客服'
|
keywords: '客服中心, 在线客服, 技术支持, 问题反馈, 天远数据客服'
|
||||||
}
|
},
|
||||||
|
'/agent/promote': {
|
||||||
|
title: '生成推广码_自定义价格_0成本代理查价系统_天远数据',
|
||||||
|
description: '天远数据推广中心支持代理自主设置报告价格。在此选择报告类型,自定义客户查询价,0成本生成专属推广链接或二维码。差价即为利润,实现个人风险报告的私域流量变现。',
|
||||||
|
keywords: '推广码生成,自定义查价系统,代理收益工具,代理推广链接,流量变现平台,天远数据推广'
|
||||||
|
},
|
||||||
|
'/agent/invitation': {
|
||||||
|
title: '邀请合作伙伴_发展代理享收益_推广返利计划_天远数据',
|
||||||
|
description: '天远数据推出合伙人邀请奖励机制。邀请好友注册成为合作伙伴,每单不仅可获得推广收益,还可叠加合作伙伴活跃奖励及定价差额收益。打造专属推广团队,实现收益持续增长。',
|
||||||
|
keywords: '渠道合作伙伴,商业收益管理,流量合规变现,业务推广系统,代理后台'
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentPath = route?.path || '/'
|
const currentPath = route?.path || '/'
|
||||||
const config = routeConfigs[currentPath] || defaultSEO
|
const config = routeConfigs[currentPath] || defaultSEO
|
||||||
|
const baseUrl = typeof window !== 'undefined' ? window.location.origin : defaultSEO.url
|
||||||
updateSEO({
|
updateSEO({
|
||||||
...config,
|
...config,
|
||||||
url: `https://www.zhinengcha.cn${currentPath}`
|
url: `${baseUrl}${currentPath}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ export function useWeixinShare() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const defaultConfig = {
|
const defaultConfig = {
|
||||||
title: "天远数据|大数据风险报告查询与代理平台,支持个人和企业多场景风控应用",
|
title: "天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台",
|
||||||
desc: "提供个人信用评估、人事背调、信贷风控、企业风险监测等服务",
|
desc: "提供个人信用评估、人事背调、信贷风控、企业风险监测等服务",
|
||||||
link: window.location.href.split("#")[0], // 获取当前页面URL,不包括hash
|
link: window.location.href.split("#")[0], // 获取当前页面URL,不包括hash
|
||||||
imgUrl: "https://www.tianyuandb.com/logo.jpg",
|
imgUrl: "https://www.tianyuandb.com/logo.jpg",
|
||||||
@@ -215,7 +215,7 @@ export function useWeixinShare() {
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
shareConfig = {
|
shareConfig = {
|
||||||
title: "天远数据|大数据风险报告查询与代理平台,支持个人和企业多场景风控应用",
|
title: "天远数据_背调报告代理加盟_个人风控系统搭建_合规数据服务平台",
|
||||||
desc: "提供个人信用评估、人事背调、信贷风控、企业风险监测等服务",
|
desc: "提供个人信用评估、人事背调、信贷风控、企业风险监测等服务",
|
||||||
link: window.location.href.split("#")[0],
|
link: window.location.href.split("#")[0],
|
||||||
imgUrl: "https://www.tianyuandb.com/logo.jpg",
|
imgUrl: "https://www.tianyuandb.com/logo.jpg",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="home-layout min-h-screen flex flex-col">
|
<div class="home-layout min-h-screen flex flex-col">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<img class="logo rounded-full overflow-hidden" src="/logo.jpg" alt="Logo" />
|
<img class="logo rounded-full overflow-hidden" src="/logo.png" alt="Logo" />
|
||||||
<div class="title">天远数据</div>
|
<div class="title">天远数据</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a class="text-blue-500" href="https://beian.miit.gov.cn">
|
<a class="text-blue-500" href="https://beian.miit.gov.cn">
|
||||||
琼ICP备2024048057号-2
|
琼ICP备2024038584号-13
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -149,12 +149,12 @@ const router = createRouter({
|
|||||||
component: () => import('@/views/AgentServiceAgreement.vue'),
|
component: () => import('@/views/AgentServiceAgreement.vue'),
|
||||||
meta: { title: '信息技术服务合同' },
|
meta: { title: '信息技术服务合同' },
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
path: '/inquire/marriage',
|
// path: '/inquire/marriage',
|
||||||
name: 'inquire-marriage',
|
// name: 'inquire-marriage',
|
||||||
component: () => import('@/views/Maintenance.vue'),
|
// component: () => import('@/views/Maintenance.vue'),
|
||||||
meta: { title: '维护通知' },
|
// meta: { title: '维护通知' },
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: '/inquire/:feature',
|
path: '/inquire/:feature',
|
||||||
name: 'inquire',
|
name: 'inquire',
|
||||||
@@ -458,7 +458,7 @@ router.afterEach((to) => {
|
|||||||
const seoConfig = {
|
const seoConfig = {
|
||||||
title: `${to.meta.title} - 天远数据`,
|
title: `${to.meta.title} - 天远数据`,
|
||||||
description: `天远数据${to.meta.title}页面,提供专业的大数据风险管控服务。`,
|
description: `天远数据${to.meta.title}页面,提供专业的大数据风险管控服务。`,
|
||||||
url: `https://www.zhinengcha.cn${to.path}`
|
url: `https://www.tianyuandb.com${to.path}`
|
||||||
}
|
}
|
||||||
updateSEO(seoConfig)
|
updateSEO(seoConfig)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { ref } from 'vue'
|
|||||||
export const useDialogStore = defineStore('dialog', () => {
|
export const useDialogStore = defineStore('dialog', () => {
|
||||||
const showBindPhone = ref(false)
|
const showBindPhone = ref(false)
|
||||||
const showRealNameAuth = ref(false)
|
const showRealNameAuth = ref(false)
|
||||||
|
const showLogin = ref(false)
|
||||||
|
|
||||||
function openBindPhone() {
|
function openBindPhone() {
|
||||||
showBindPhone.value = true
|
showBindPhone.value = true
|
||||||
@@ -21,6 +22,14 @@ export const useDialogStore = defineStore('dialog', () => {
|
|||||||
showRealNameAuth.value = false
|
showRealNameAuth.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openLogin() {
|
||||||
|
showLogin.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeLogin() {
|
||||||
|
showLogin.value = false
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
showBindPhone,
|
showBindPhone,
|
||||||
openBindPhone,
|
openBindPhone,
|
||||||
@@ -28,5 +37,8 @@ export const useDialogStore = defineStore('dialog', () => {
|
|||||||
showRealNameAuth,
|
showRealNameAuth,
|
||||||
openRealNameAuth,
|
openRealNameAuth,
|
||||||
closeRealNameAuth,
|
closeRealNameAuth,
|
||||||
|
showLogin,
|
||||||
|
openLogin,
|
||||||
|
closeLogin,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
BIN
src/ui.zip
BIN
src/ui.zip
Binary file not shown.
104
src/ui/CIVYZ6M8P.vue
Normal file
104
src/ui/CIVYZ6M8P.vue
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<div class="card">
|
||||||
|
<div class="header-box">
|
||||||
|
<h3 class="header-title">职业资格证书查询</h3>
|
||||||
|
<p class="header-desc">展示查询到的职业资格考试及等级信息</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="hasData" class="result-section">
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">考试名称</span>
|
||||||
|
<span class="info-value">{{ examName || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">级别</span>
|
||||||
|
<span class="info-value">{{ level || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">专业</span>
|
||||||
|
<span class="info-value">{{ major || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="info-label">通过日期</span>
|
||||||
|
<span class="info-value">{{ passDate || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="hasData && !examName && !major && !level && !passDate" class="empty-tip">
|
||||||
|
已返回结果,但格式不在预期范围内,请联系技术支持查看原始数据。
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!hasData" class="empty-tip">暂无查询结果</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
data: { type: Object, default: () => ({}) },
|
||||||
|
params: { type: Object, default: () => ({}) },
|
||||||
|
apiId: { type: String, default: '' },
|
||||||
|
index: { type: Number, default: 0 },
|
||||||
|
notifyRiskStatus: { type: Function, default: () => { } },
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasData = computed(() => props.data && Object.keys(props.data).length > 0);
|
||||||
|
|
||||||
|
// ED0001: 考试名称, ED0002: 级别, ED0003: 专业, ED0004: 通过年月
|
||||||
|
const examName = computed(() => props.data?.ED0001 || '');
|
||||||
|
const level = computed(() => props.data?.ED0002 || '');
|
||||||
|
const major = computed(() => props.data?.ED0003 || '');
|
||||||
|
const passDate = computed(() => props.data?.ED0004 || '');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.card {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-box {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-desc {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #6b7280;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-section {
|
||||||
|
background: #f9fafb;
|
||||||
|
padding: 0.75rem 0.875rem;
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
padding: 0.25rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value {
|
||||||
|
color: #111827;
|
||||||
|
margin-left: 1rem;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-tip {
|
||||||
|
color: #9ca3af;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
padding: 1rem 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -63,16 +63,17 @@ const currentStatus = !actualData
|
|||||||
:class="`status-label rounded-full px-6 py-3 text-center font-bold shadow-md ${currentStatus.bgClass} ${currentStatus.textClass}`">
|
:class="`status-label rounded-full px-6 py-3 text-center font-bold shadow-md ${currentStatus.bgClass} ${currentStatus.textClass}`">
|
||||||
{{ currentStatus.text }}
|
{{ currentStatus.text }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="currentStatus.opDate" class="op-date-container mt-4 px-4 py-2 bg-blue-50 rounded-lg border border-blue-200">
|
|
||||||
<p class="op-date text-sm font-medium text-blue-700">
|
|
||||||
登记日期:{{ currentStatus.opDate }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<p v-html="currentStatus.description" class="status-description mt-3 text-sm text-gray-600"></p>
|
<p v-html="currentStatus.description" class="status-description mt-3 text-sm text-gray-600"></p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- <div v-if="currentStatus.opDate" class="op-date-container mt-4 px-4 py-2 bg-blue-50 rounded-lg border border-blue-200">
|
||||||
|
<p class="op-date text-sm font-medium text-blue-700">
|
||||||
|
登记日期:{{ currentStatus.opDate }}
|
||||||
|
</p>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.status-info {
|
.status-info {
|
||||||
|
|||||||
524
src/ui/IVYZ0S0D.vue
Normal file
524
src/ui/IVYZ0S0D.vue
Normal file
@@ -0,0 +1,524 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { useRiskNotifier } from '@/composables/useRiskNotifier';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
data: { type: Object, default: () => ({}) },
|
||||||
|
params: { type: Object, default: () => ({}) },
|
||||||
|
apiId: { type: String, default: '' },
|
||||||
|
index: { type: Number, default: 0 },
|
||||||
|
notifyRiskStatus: { type: Function, default: () => { } },
|
||||||
|
});
|
||||||
|
|
||||||
|
const periodTab = ref('threeYears'); // 近三年 | 近五年
|
||||||
|
|
||||||
|
// 支持 data 或 data.result(接口返回的 result 对象)
|
||||||
|
const result = computed(() => props.data?.result ?? props.data ?? {});
|
||||||
|
|
||||||
|
const getStatusText = (value) => {
|
||||||
|
if (value === 1) return '未命中';
|
||||||
|
if (value === 2) return '命中';
|
||||||
|
return '—';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取通知函期间描述文本(支持数字或字符串如 "2")
|
||||||
|
const getNoticeLetterPeriodText = (period) => {
|
||||||
|
const p = Number(period);
|
||||||
|
const periodMap = { 0: '没有被发送通知函', 1: '近2年内', 2: '2-4年', 3: '5年以上' };
|
||||||
|
return periodMap[p] ?? '—';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 检查是否至少有一个数据类别有内容
|
||||||
|
const hasAnyData = computed(() => {
|
||||||
|
const r = result.value;
|
||||||
|
return Object.keys(r).length > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 汇总数据 - 按分类分组 { key, title, rows }
|
||||||
|
const summaryGroups = computed(() => {
|
||||||
|
const groups = [];
|
||||||
|
const basic = result.value.basic_info;
|
||||||
|
if (basic?.risk_flag !== undefined) {
|
||||||
|
groups.push({ key: 'basic', title: '基础风险', rows: [{ label: '该人员是否有风险', value: basic.risk_flag }] });
|
||||||
|
}
|
||||||
|
const dishonesty = result.value.dishonesty?.dishonesty;
|
||||||
|
const highConsumption = result.value.high_consumption?.high_consumption;
|
||||||
|
if (dishonesty !== undefined || highConsumption !== undefined) {
|
||||||
|
const rows = [];
|
||||||
|
if (dishonesty !== undefined) rows.push({ label: '失信人员风险', value: dishonesty });
|
||||||
|
if (highConsumption !== undefined) rows.push({ label: '限制高消费人员风险', value: highConsumption });
|
||||||
|
groups.push({ key: 'credit', title: '失信限高', rows });
|
||||||
|
}
|
||||||
|
const labor = result.value.labor_disputes;
|
||||||
|
if (labor) {
|
||||||
|
const items = [['劳动争议', labor.labor_disputes], ['劳动合同纠纷', labor.labor_contract], ['劳动关系纠纷', labor.labor_relation], ['追索劳动报酬纠纷', labor.wage_claim], ['经济补偿金纠纷', labor.compensation], ['集体合同纠纷', labor.collective_contract], ['劳务派遣合同纠纷', labor.dispatch_contract], ['非全日制用工纠纷', labor.part_time], ['竞业限制纠纷', labor.non_compete]];
|
||||||
|
const rows = items.filter((item) => item[1] !== undefined).map((item) => ({ label: item[0], value: item[1] }));
|
||||||
|
if (rows.length) groups.push({ key: 'labor', title: '劳动争议', rows });
|
||||||
|
}
|
||||||
|
const social = result.value.social_insurance;
|
||||||
|
if (social) {
|
||||||
|
const items = [['社会保险纠纷', social.social_insurance], ['养老保险待遇纠纷', social.pension], ['工伤保险待遇纠纷', social.injury_insurance], ['医疗保险待遇纠纷', social.medical_insurance], ['生育保险待遇纠纷', social.maternity_insurance], ['商业保险待遇纠纷', social.commercial_insurance]];
|
||||||
|
const rows = items.filter((item) => item[1] !== undefined).map((item) => ({ label: item[0], value: item[1] }));
|
||||||
|
if (rows.length) groups.push({ key: 'social', title: '社会保险', rows });
|
||||||
|
}
|
||||||
|
if (result.value.welfare_disputes?.welfare !== undefined) {
|
||||||
|
groups.push({ key: 'welfare', title: '福利待遇', rows: [{ label: '福利待遇纠纷', value: result.value.welfare_disputes.welfare }] });
|
||||||
|
}
|
||||||
|
const personnel = result.value.personnel_disputes;
|
||||||
|
if (personnel) {
|
||||||
|
const items = [['人事争议类纠纷', personnel.personnel_dispute], ['辞职争议纠纷', personnel.resignation_dispute], ['辞退争议纠纷', personnel.dismissal_dispute], ['聘用合同争议纠纷', personnel.employment_contract]];
|
||||||
|
const rows = items.filter((item) => item[1] !== undefined).map((item) => ({ label: item[0], value: item[1] }));
|
||||||
|
if (rows.length) groups.push({ key: 'personnel', title: '人事争议', rows });
|
||||||
|
}
|
||||||
|
const arb = result.value.arbitration;
|
||||||
|
if (arb && (arb.arbitration_confirmation !== undefined || arb.arbitration_revocation !== undefined)) {
|
||||||
|
const rows = [];
|
||||||
|
if (arb.arbitration_confirmation !== undefined) rows.push({ label: '申请仲裁确认', value: arb.arbitration_confirmation });
|
||||||
|
if (arb.arbitration_revocation !== undefined) rows.push({ label: '撤销仲裁裁决', value: arb.arbitration_revocation });
|
||||||
|
groups.push({ key: 'arbitration', title: '仲裁流程', rows });
|
||||||
|
}
|
||||||
|
const notice = result.value.notice_letter;
|
||||||
|
if (notice?.notice_letter !== undefined) {
|
||||||
|
const rows = [{ label: '通知函触达', value: notice.notice_letter }];
|
||||||
|
if (notice.notice_letter_period !== undefined && notice.notice_letter === 2) rows.push({ label: '通知函发送时间', value: null, period: notice.notice_letter_period });
|
||||||
|
groups.push({ key: 'notice', title: '通知函触达', rows });
|
||||||
|
}
|
||||||
|
return groups;
|
||||||
|
});
|
||||||
|
|
||||||
|
const summaryRows = computed(() => summaryGroups.value.flatMap((g) => g.rows));
|
||||||
|
|
||||||
|
// 真正的风险项(文档:失信限高、劳动争议、社会保险、福利待遇、人事争议、仲裁流程、通知函触达)
|
||||||
|
// 排除 basic_info.risk_flag(汇总结论)和 notice_letter_period(非风险项)
|
||||||
|
const riskItemRows = computed(() =>
|
||||||
|
summaryGroups.value
|
||||||
|
.filter((g) => g.key !== 'basic')
|
||||||
|
.flatMap((g) => g.rows)
|
||||||
|
.filter((r) => r.value === 1 || r.value === 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 近三年/近五年 - 按分类分组
|
||||||
|
const periodGroups = computed(() => {
|
||||||
|
const suffix = periodTab.value === 'threeYears' ? '_3y' : '_5y';
|
||||||
|
const groups = [];
|
||||||
|
const labor = result.value.labor_disputes;
|
||||||
|
if (labor) {
|
||||||
|
const keys = ['labor_disputes', 'labor_relation', 'wage_claim', 'compensation', 'collective_contract', 'dispatch_contract', 'part_time', 'non_compete'];
|
||||||
|
const labels = ['劳动争议', '劳动关系', '追索劳动报酬', '经济补偿金', '集体合同', '劳务派遣', '非全日制用工', '竞业限制'];
|
||||||
|
const rows = keys.map((k, i) => ({ label: labels[i], value: labor[k + suffix] })).filter((r) => r.value === 2).map((r) => ({ label: r.label, value: 2 }));
|
||||||
|
if (rows.length) groups.push({ key: 'labor', title: '劳动争议', rows });
|
||||||
|
}
|
||||||
|
const social = result.value.social_insurance;
|
||||||
|
if (social) {
|
||||||
|
const keys = ['pension', 'injury_insurance', 'medical_insurance', 'maternity_insurance', 'commercial_insurance'];
|
||||||
|
const labels = ['养老保险', '工伤保险', '医疗保险', '生育保险', '商业保险'];
|
||||||
|
const rows = keys.map((k, i) => ({ label: labels[i], value: social[k + suffix] })).filter((r) => r.value === 2).map((r) => ({ label: r.label, value: 2 }));
|
||||||
|
if (rows.length) groups.push({ key: 'social', title: '社会保险', rows });
|
||||||
|
}
|
||||||
|
const personnel = result.value.personnel_disputes;
|
||||||
|
if (personnel) {
|
||||||
|
const keys = ['resignation_dispute', 'dismissal_dispute', 'employment_contract'];
|
||||||
|
const labels = ['辞职争议', '辞退争议', '聘用合同'];
|
||||||
|
const rows = keys.map((k, i) => ({ label: labels[i], value: personnel[k + suffix] })).filter((r) => r.value === 2).map((r) => ({ label: r.label, value: 2 }));
|
||||||
|
if (rows.length) groups.push({ key: 'personnel', title: '人事争议', rows });
|
||||||
|
}
|
||||||
|
const arb = result.value.arbitration;
|
||||||
|
if (arb) {
|
||||||
|
const rows = [];
|
||||||
|
if (arb[`arbitration_confirmation${suffix}`] === 2) rows.push({ label: '申请仲裁确认', value: 2 });
|
||||||
|
if (arb[`arbitration_revocation${suffix}`] === 2) rows.push({ label: '撤销仲裁裁决', value: 2 });
|
||||||
|
if (rows.length) groups.push({ key: 'arbitration', title: '仲裁流程', rows });
|
||||||
|
}
|
||||||
|
return groups;
|
||||||
|
});
|
||||||
|
|
||||||
|
const periodRows = computed(() => periodGroups.value.flatMap((g) => g.rows));
|
||||||
|
|
||||||
|
// 用于 riskScore:需要近三年+近五年全部数据
|
||||||
|
const recentThreeYearsRows = computed(() => {
|
||||||
|
const r = result.value;
|
||||||
|
const rows = [];
|
||||||
|
const labor = r.labor_disputes;
|
||||||
|
if (labor) {
|
||||||
|
[['labor_disputes_3y'], ['labor_relation_3y'], ['wage_claim_3y'], ['compensation_3y'], ['collective_contract_3y'], ['dispatch_contract_3y'], ['part_time_3y'], ['non_compete_3y']].forEach(([k]) => { if (labor[k] === 2) rows.push({ value: 2 }); });
|
||||||
|
}
|
||||||
|
const social = r.social_insurance;
|
||||||
|
if (social) {
|
||||||
|
['pension_3y', 'injury_insurance_3y', 'medical_insurance_3y', 'maternity_insurance_3y', 'commercial_insurance_3y'].forEach((k) => { if (social[k] === 2) rows.push({ value: 2 }); });
|
||||||
|
}
|
||||||
|
const personnel = r.personnel_disputes;
|
||||||
|
if (personnel) {
|
||||||
|
['resignation_dispute_3y', 'dismissal_dispute_3y', 'employment_contract_3y'].forEach((k) => { if (personnel[k] === 2) rows.push({ value: 2 }); });
|
||||||
|
}
|
||||||
|
const arb = r.arbitration;
|
||||||
|
if (arb) {
|
||||||
|
if (arb.arbitration_confirmation_3y === 2) rows.push({ value: 2 });
|
||||||
|
if (arb.arbitration_revocation_3y === 2) rows.push({ value: 2 });
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
});
|
||||||
|
const recentFiveYearsRows = computed(() => {
|
||||||
|
const r = result.value;
|
||||||
|
const rows = [];
|
||||||
|
const labor = r.labor_disputes;
|
||||||
|
if (labor) {
|
||||||
|
[['labor_disputes_5y'], ['labor_relation_5y'], ['wage_claim_5y'], ['compensation_5y'], ['collective_contract_5y'], ['dispatch_contract_5y'], ['part_time_5y'], ['non_compete_5y']].forEach(([k]) => { if (labor[k] === 2) rows.push({ value: 2 }); });
|
||||||
|
}
|
||||||
|
const social = r.social_insurance;
|
||||||
|
if (social) {
|
||||||
|
['pension_5y', 'injury_insurance_5y', 'medical_insurance_5y', 'maternity_insurance_5y', 'commercial_insurance_5y'].forEach((k) => { if (social[k] === 2) rows.push({ value: 2 }); });
|
||||||
|
}
|
||||||
|
const personnel = r.personnel_disputes;
|
||||||
|
if (personnel) {
|
||||||
|
['resignation_dispute_5y', 'dismissal_dispute_5y', 'employment_contract_5y'].forEach((k) => { if (personnel[k] === 2) rows.push({ value: 2 }); });
|
||||||
|
}
|
||||||
|
const arb = r.arbitration;
|
||||||
|
if (arb) {
|
||||||
|
if (arb.arbitration_confirmation_5y === 2) rows.push({ value: 2 });
|
||||||
|
if (arb.arbitration_revocation_5y === 2) rows.push({ value: 2 });
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 头部风险总结:风险类型、建议、命中统计(仅真正的风险项)
|
||||||
|
const riskSummary = computed(() => {
|
||||||
|
const basic = result.value.basic_info;
|
||||||
|
const hasRisk = basic?.risk_flag === 2;
|
||||||
|
|
||||||
|
// 真正的风险项:总项数、命中数(文档:失信限高、劳动争议、社会保险、福利待遇、人事争议、仲裁流程、通知函触达)
|
||||||
|
const totalItems = riskItemRows.value.length;
|
||||||
|
const hitItems = riskItemRows.value.filter((r) => r.value === 2).length;
|
||||||
|
|
||||||
|
// 命中的风险分类(汇总中 value=2 的 group)
|
||||||
|
const riskCategories = summaryGroups.value
|
||||||
|
.filter((g) => g.key !== 'basic' && g.rows.some((r) => r.value === 2))
|
||||||
|
.map((g) => g.title);
|
||||||
|
|
||||||
|
// 精简建议(取主要类型合并为一句)
|
||||||
|
const suggestionMap = {
|
||||||
|
'失信限高': '征信修复与限高事项',
|
||||||
|
'劳动争议': '劳动纠纷与薪酬离职',
|
||||||
|
'社会保险': '社保缴纳与补缴',
|
||||||
|
'福利待遇': '福利待遇合规',
|
||||||
|
'人事争议': '辞职辞退与聘用合同',
|
||||||
|
'仲裁流程': '仲裁案件进展',
|
||||||
|
'通知函触达': '仲裁调解涉诉通知',
|
||||||
|
};
|
||||||
|
const suggestionParts = riskCategories.map((c) => suggestionMap[c]).filter(Boolean);
|
||||||
|
const suggestion = suggestionParts.length ? `建议关注${suggestionParts.slice(0, 3).join('、')}。` : '';
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasRisk,
|
||||||
|
label: hasRisk ? '有风险' : '无风险',
|
||||||
|
riskCategories,
|
||||||
|
suggestion,
|
||||||
|
totalItems,
|
||||||
|
hitItems,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// 风险评分 0-100,越高越安全(供 BaseReport 分析指数)
|
||||||
|
// 基于真正的风险项(riskItemRows),与展示逻辑一致,通过 useRiskNotifier 递交 BaseReport
|
||||||
|
const riskScore = computed(() => {
|
||||||
|
const basic = result.value.basic_info;
|
||||||
|
if (!basic || basic.risk_flag === 1) return 100;
|
||||||
|
const hitItems = riskItemRows.value.filter((r) => r.value === 2).length;
|
||||||
|
const score = 100 - hitItems * 2; // 每命中 1 项扣 2 分
|
||||||
|
return Math.max(0, Math.min(100, score));
|
||||||
|
});
|
||||||
|
useRiskNotifier(props, riskScore);
|
||||||
|
defineExpose({ riskScore });
|
||||||
|
|
||||||
|
// 借鉴司法涉诉概览:风险图标与背景样式
|
||||||
|
const getRiskIcon = () => {
|
||||||
|
if (riskSummary.value.hasRisk) return new URL('@/assets/images/report/gfx.png', import.meta.url).href;
|
||||||
|
return new URL('@/assets/images/report/zq.png', import.meta.url).href;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="report-wrap">
|
||||||
|
<!-- 头部风险总结(底色固定白色,命中项用内嵌 card 展现) -->
|
||||||
|
<div v-if="hasAnyData" class="risk-summary card">
|
||||||
|
<div class="flex items-center mb-4">
|
||||||
|
<div class="w-12 h-12 mr-3 flex-shrink-0">
|
||||||
|
<img :src="getRiskIcon()" alt="风险" class="w-12 h-12 object-contain" />
|
||||||
|
</div>
|
||||||
|
<div class="text-gray-700 text-[15px] leading-relaxed">
|
||||||
|
<template v-if="riskSummary.hasRisk">
|
||||||
|
<span v-if="riskSummary.riskCategories.length">涉及{{ riskSummary.riskCategories.join('、')
|
||||||
|
}};</span>
|
||||||
|
<span v-if="riskSummary.suggestion">{{ riskSummary.suggestion }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-else>未检测到相关风险</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 命中项:仅显示总项数 / 命中数(真正的风险项:失信限高、劳动争议、社会保险、福利待遇、人事争议、仲裁流程、通知函触达) -->
|
||||||
|
<div v-if="riskSummary.totalItems > 0" class="inner-card p-4 rounded-xl text-center"
|
||||||
|
:class="riskSummary.hitItems > 0 ? 'inner-card-risk' : 'inner-card-safe'">
|
||||||
|
<div class="text-2xl font-bold mb-1"
|
||||||
|
:class="riskSummary.hitItems > 0 ? 'text-[#EB3C3C]' : 'text-[#10b981]'">
|
||||||
|
{{ riskSummary.hitItems }}/{{ riskSummary.totalItems }}
|
||||||
|
</div>
|
||||||
|
<div class="text-sm font-medium text-gray-800">命中项</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Card 1: 汇总 -->
|
||||||
|
<section class="card">
|
||||||
|
<header class="card-header">
|
||||||
|
<span class="card-title">风险概览</span>
|
||||||
|
<span class="card-subtitle">综合评估结果</span>
|
||||||
|
</header>
|
||||||
|
<div v-if="hasAnyData" class="group-list">
|
||||||
|
<div v-for="(group, gi) in summaryGroups" :key="group.key" class="group-box">
|
||||||
|
<div class="group-header">
|
||||||
|
<span class="group-title">{{ group.title }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="group-body">
|
||||||
|
<div v-for="(row, ri) in group.rows" :key="ri" class="data-row">
|
||||||
|
<span class="data-label">{{ row.label }}</span>
|
||||||
|
<span v-if="row.period !== undefined" class="data-value data-value-text">{{
|
||||||
|
getNoticeLetterPeriodText(row.period) }}</span>
|
||||||
|
<span v-else
|
||||||
|
:class="['data-value', 'data-badge', row.value === 2 ? 'badge-risk' : 'badge-safe']">
|
||||||
|
<span class="badge-dot" :class="row.value === 2 ? 'dot-risk' : 'dot-safe'" />
|
||||||
|
{{ getStatusText(row.value) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="empty-state">
|
||||||
|
<span class="empty-icon">—</span>
|
||||||
|
<span class="empty-text">暂无相关风险数据</span>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Card 2: 近三年 / 近五年 -->
|
||||||
|
<section class="card">
|
||||||
|
<header class="card-header">
|
||||||
|
<span class="card-title">时间维度</span>
|
||||||
|
<span class="card-subtitle">按周期查看命中情况</span>
|
||||||
|
</header>
|
||||||
|
<div class="period-tabs">
|
||||||
|
<button type="button" :class="['period-tab', periodTab === 'threeYears' && 'active']"
|
||||||
|
@click="periodTab = 'threeYears'">近三年</button>
|
||||||
|
<button type="button" :class="['period-tab', periodTab === 'fiveYears' && 'active']"
|
||||||
|
@click="periodTab = 'fiveYears'">近五年</button>
|
||||||
|
</div>
|
||||||
|
<div v-if="periodGroups.length" class="group-list">
|
||||||
|
<div v-for="(group, gi) in periodGroups" :key="group.key" class="group-box">
|
||||||
|
<div class="group-header">
|
||||||
|
<span class="group-title">{{ group.title }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="group-body">
|
||||||
|
<div v-for="(row, ri) in group.rows" :key="ri" class="data-row">
|
||||||
|
<span class="data-label">{{ row.label }}</span>
|
||||||
|
<span class="data-value data-badge badge-risk">
|
||||||
|
<span class="badge-dot dot-risk" />
|
||||||
|
{{ getStatusText(row.value) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="empty-state">
|
||||||
|
<span class="empty-icon">—</span>
|
||||||
|
<span class="empty-text">暂无{{ periodTab === 'threeYears' ? '近三年' : '近五年' }}命中数据</span>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.report-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 16px;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner-card {
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner-card-risk {
|
||||||
|
background: rgba(235, 60, 60, 0.1);
|
||||||
|
border-color: rgba(235, 60, 60, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner-card-safe {
|
||||||
|
background: rgba(16, 185, 129, 0.1);
|
||||||
|
border-color: rgba(16, 185, 129, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
border-bottom: 1px solid #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1e293b;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-subtitle {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #94a3b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period-tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
padding: 4px;
|
||||||
|
background: #f8fafc;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period-tab {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px 16px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #64748b;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.period-tab.active {
|
||||||
|
color: #1e293b;
|
||||||
|
font-weight: 500;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-box {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-header {
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #f8fafc;
|
||||||
|
border-bottom: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #475569;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-row:not(:last-child) {
|
||||||
|
border-bottom: 1px solid #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-label {
|
||||||
|
color: #475569;
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 12px;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-value {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-value-text {
|
||||||
|
color: #64748b;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-dot {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-risk {
|
||||||
|
background: #fff1f2;
|
||||||
|
color: #be123c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-risk {
|
||||||
|
background: #e11d48;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-safe {
|
||||||
|
background: #f0fdf4;
|
||||||
|
color: #047857;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-safe {
|
||||||
|
background: #10b981;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 28px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #cbd5e1;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #94a3b8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
149
src/ui/JRZQ8B3C/README.md
Normal file
149
src/ui/JRZQ8B3C/README.md
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
# 个人消费能力等级组件 (JRZQ8B3C)
|
||||||
|
|
||||||
|
## 组件概述
|
||||||
|
|
||||||
|
基于个人收入指数评分进行消费能力等级评估,为企业提供专业的消费能力分析和风险评估服务。
|
||||||
|
|
||||||
|
## 组件结构
|
||||||
|
|
||||||
|
```
|
||||||
|
JRZQ8B3C/
|
||||||
|
├── index.vue # 主组件
|
||||||
|
└── README.md # 说明文档
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
### 基本用法
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<JRZQ8B3C :data="consumptionData" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import JRZQ8B3C from '@/ui/JRZQ8B3C/index.vue'
|
||||||
|
|
||||||
|
// 个人消费能力等级数据示例
|
||||||
|
const consumptionData = {
|
||||||
|
personincome_index_2.0: "200" // 个人收入指数评分(字符串类型)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 数据字段说明
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 必填 | 描述 | 示例值 |
|
||||||
|
|-------|------|------|------|--------|
|
||||||
|
| personincome_index_2.0 | String | 是 | 个人收入指数评分 | "200" |
|
||||||
|
|
||||||
|
## 评分分档说明
|
||||||
|
|
||||||
|
| 分值 | 收入区间(元/月) | 消费能力等级 | 风险等级 |
|
||||||
|
|------|----------------|------------|----------|
|
||||||
|
| -1 | **未命中** | 无法获取收入信息 | 高风险 |
|
||||||
|
| 100 | (1000, 2000] | 第1档 | 高风险 |
|
||||||
|
| 200 | (2000, 4000] | 第2档 | 高风险 |
|
||||||
|
| 300 | (4000, 6000] | 第3档 | 高风险 |
|
||||||
|
| 400 | (6000, 8000] | 第4档 | 中等风险 |
|
||||||
|
| 500 | (8000, 10000] | 第5档 | 中等风险 |
|
||||||
|
| 600 | (10000, 12000] | 第6档 | 中等风险 |
|
||||||
|
| 700 | (12000, 15000] | 第7档 | 低风险 |
|
||||||
|
| 800 | (15000, 20000] | 第8档 | 低风险 |
|
||||||
|
| 900 | (20000, 25000] | 第9档 | 低风险 |
|
||||||
|
| 1000 | (25000, +∞) | 第10档 | 低风险 |
|
||||||
|
|
||||||
|
## 特殊值说明
|
||||||
|
|
||||||
|
- **-1**: 表示未命中(无法获取收入信息)
|
||||||
|
- **评分范围**: 100-1000分,共10个等级
|
||||||
|
- **等级意义**: 等级越高,对应的消费能力越强
|
||||||
|
- **区间定义**: 收入区间为左开右闭区间(如:1000 < 收入 ≤ 2000)
|
||||||
|
|
||||||
|
## 组件特性
|
||||||
|
|
||||||
|
### 1. 专业的视觉展示
|
||||||
|
- **评分展示**:大数字显示个人收入指数评分
|
||||||
|
- **进度条可视化**:直观展示评分在100-1000分范围内的位置
|
||||||
|
- **颜色编码**:根据评分等级使用不同颜色(低=红色,中=黄色,高=绿色)
|
||||||
|
- **响应式设计**:完美适配各种屏幕尺寸
|
||||||
|
|
||||||
|
### 2. 全面的数据分析
|
||||||
|
- **收入区间显示**:清晰展示对应的月收入范围
|
||||||
|
- **等级描述**:显示当前评分对应的消费能力等级
|
||||||
|
- **市场对比分析**:与市场平均水平对比
|
||||||
|
- **消费能力评估**:基于收入指数的消费能力分析
|
||||||
|
|
||||||
|
### 3. 智能风险评估
|
||||||
|
- **动态评分**:根据收入指数自动计算风险分数(30-100分)
|
||||||
|
- **风险等级标签**:直观显示当前风险等级
|
||||||
|
- **个性化建议**:针对不同等级的专业建议
|
||||||
|
|
||||||
|
## 视觉设计亮点
|
||||||
|
|
||||||
|
### 1. 色彩系统
|
||||||
|
- **低风险(700-1000分)**:绿色系,表示消费能力强
|
||||||
|
- **中等风险(400-600分)**:黄色系,表示消费能力中等
|
||||||
|
- **高风险(100-300分/-1)**:红色系,表示消费能力有限
|
||||||
|
|
||||||
|
### 2. 交互体验
|
||||||
|
- 平滑的动画过渡
|
||||||
|
- 直观的视觉反馈
|
||||||
|
- 清晰的信息层次
|
||||||
|
|
||||||
|
### 3. 信息架构
|
||||||
|
- 层次分明的信息展示
|
||||||
|
- 重点突出的核心数据
|
||||||
|
- 完整的补充说明
|
||||||
|
|
||||||
|
## 数据说明
|
||||||
|
|
||||||
|
### 评估依据
|
||||||
|
- 基于个人收入指数评分
|
||||||
|
- 使用10档分级评分体系
|
||||||
|
- 数据准确可靠
|
||||||
|
|
||||||
|
### 使用限制
|
||||||
|
- 收入范围为税前月收入
|
||||||
|
- 存在地区差异,仅供参考
|
||||||
|
- 建议结合其他收入证明材料
|
||||||
|
|
||||||
|
### 评分计算
|
||||||
|
- 风险评分范围:30-100分
|
||||||
|
- 100分对应30分风险评分
|
||||||
|
- 1000分对应100分风险评分(最安全)
|
||||||
|
- -1(未命中)对应30分风险评分
|
||||||
|
|
||||||
|
## 业务价值
|
||||||
|
|
||||||
|
### 1. 风险控制
|
||||||
|
- 精确的消费能力评估降低信贷风险
|
||||||
|
- 多维度风险分析提升决策质量
|
||||||
|
- 智能化评分系统提高效率
|
||||||
|
|
||||||
|
### 2. 客户分层
|
||||||
|
- 基于消费能力的客户分级管理
|
||||||
|
- 个性化服务策略制定
|
||||||
|
- 精准的市场定位分析
|
||||||
|
|
||||||
|
### 3. 合规要求
|
||||||
|
- 符合金融监管要求
|
||||||
|
- 数据来源权威可靠
|
||||||
|
- 评估过程透明公开
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 确保传入正确的 `personincome_index_2.0` 值
|
||||||
|
2. 组件会自动处理 -1 特殊值(未命中)
|
||||||
|
3. 建议在网络良好的环境下使用
|
||||||
|
4. 定期更新评估标准以保持准确性
|
||||||
|
|
||||||
|
## 更新日志
|
||||||
|
|
||||||
|
- v1.0.0 - 初始版本,支持基础消费能力等级评估功能
|
||||||
|
- 专业的视觉展示效果
|
||||||
|
- 完整的评分分档系统
|
||||||
|
- 专业的风险分析功能
|
||||||
|
|
||||||
377
src/ui/JRZQ8B3C/index.vue
Normal file
377
src/ui/JRZQ8B3C/index.vue
Normal file
@@ -0,0 +1,377 @@
|
|||||||
|
<template>
|
||||||
|
<div class="card">
|
||||||
|
<div class="rounded-lg border border-gray-200 pb-2 mb-4">
|
||||||
|
|
||||||
|
<!-- 标题区域 -->
|
||||||
|
<div class="flex items-center mb-4 p-4">
|
||||||
|
<div class="w-8 h-8 flex items-center justify-center mr-2">
|
||||||
|
<img src="@/assets/images/report/srpg.png" alt="个人消费能力等级" class="w-8 h-8 object-contain" />
|
||||||
|
</div>
|
||||||
|
<span class="font-bold text-gray-800">个人消费能力等级</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="px-4 pb-4">
|
||||||
|
<!-- 月消费能力 -->
|
||||||
|
<div class="mb-6 text-center">
|
||||||
|
<div class="text-sm text-gray-600 mb-2">月消费能力</div>
|
||||||
|
<div class="text-3xl font-bold mb-3 text-[#333333]">
|
||||||
|
<span class="amount-number">{{ getConsumptionAmount(score) }}</span>
|
||||||
|
<span class="amount-unit">元/月</span>
|
||||||
|
</div>
|
||||||
|
<div class="level-bar" :style="getLevelBarBgStyle(score)">
|
||||||
|
<div class="level-fill" :style="getLevelBarStyle(score)"></div>
|
||||||
|
</div>
|
||||||
|
<div class="text-sm text-gray-600 mt-2">{{ getConsumptionDescription(score) }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 评估结果 -->
|
||||||
|
<div class="assessment-card">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<h4 class="font-semibold text-gray-800">评估结果</h4>
|
||||||
|
</div>
|
||||||
|
<p class="text-gray-400 text-sm">
|
||||||
|
{{ getAssessmentDescription(score) }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 市场对比 -->
|
||||||
|
<div class="assessment-card">
|
||||||
|
<div class="flex items-center mb-8">
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<h4 class="font-semibold text-gray-800">市场对比</h4>
|
||||||
|
</div>
|
||||||
|
<p class="text-gray-400 text-sm">
|
||||||
|
{{ getMarketComparison(score) }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="comparison-indicator mt-4">
|
||||||
|
<div class="indicator-bar">
|
||||||
|
<div class="indicator-fill" :style="getIndicatorStyle(score)"></div>
|
||||||
|
<div class="indicator-marker" :style="getMarkerPosition(score)">
|
||||||
|
<img src="@/assets/images/report/srbq.png" alt="市场对比" class="marker-image" />
|
||||||
|
<div class="marker-dot"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="indicator-labels">
|
||||||
|
<span>低消费</span>
|
||||||
|
<span>高消费</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 消费能力 -->
|
||||||
|
<div class="assessment-card">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="mb-2">
|
||||||
|
<h4 class="font-semibold text-gray-800">消费能力</h4>
|
||||||
|
</div>
|
||||||
|
<p class="text-gray-400 text-sm">
|
||||||
|
{{ getConsumptionCapacity(score) }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useRiskNotifier } from '@/composables/useRiskNotifier';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
apiId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
index: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
notifyRiskStatus: {
|
||||||
|
type: Function,
|
||||||
|
default: () => { },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// 确保data是响应式的
|
||||||
|
const data = computed(() => props.data || {})
|
||||||
|
|
||||||
|
// 获取评分值(字符串转数字,处理-1特殊值)
|
||||||
|
const score = computed(() => {
|
||||||
|
const value = data.value['personincome_index_2.0'];
|
||||||
|
if (!value || value === '-1') return -1;
|
||||||
|
const num = parseInt(value, 10);
|
||||||
|
return isNaN(num) ? -1 : num;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取消费金额显示(直接显示金额区间)
|
||||||
|
const getConsumptionAmount = (score) => {
|
||||||
|
if (score === -1) return '无法评估'
|
||||||
|
|
||||||
|
const amountMap = {
|
||||||
|
100: '2,000 - 4,000',
|
||||||
|
200: '2,000 - 4,000',
|
||||||
|
300: '4,000 - 6,000',
|
||||||
|
400: '6,000 - 8,000',
|
||||||
|
500: '8,000 - 10,000',
|
||||||
|
600: '10,000 - 12,000',
|
||||||
|
700: '12,000 - 15,000',
|
||||||
|
800: '15,000 - 20,000',
|
||||||
|
900: '20,000 - 25,000',
|
||||||
|
1000: '25,000+'
|
||||||
|
}
|
||||||
|
return amountMap[score] || '数据异常'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 消费能力描述
|
||||||
|
const getConsumptionDescription = (score) => {
|
||||||
|
if (score === -1) return '暂未发现消费能力信息'
|
||||||
|
|
||||||
|
const descriptionMap = {
|
||||||
|
100: '基础消费能力',
|
||||||
|
200: '基础消费能力',
|
||||||
|
300: '中等消费能力',
|
||||||
|
400: '中等消费能力',
|
||||||
|
500: '良好消费能力',
|
||||||
|
600: '良好消费能力',
|
||||||
|
700: '较强消费能力',
|
||||||
|
800: '较强消费能力',
|
||||||
|
900: '很强消费能力',
|
||||||
|
1000: '很强消费能力'
|
||||||
|
}
|
||||||
|
return descriptionMap[score] || '数据异常'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等级进度条样式
|
||||||
|
const getLevelBarStyle = (score) => {
|
||||||
|
if (score === -1) {
|
||||||
|
return {
|
||||||
|
width: '0%',
|
||||||
|
background: '#94a3b8'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算百分比:100分=10%, 200分=20%, ..., 1000分=100%
|
||||||
|
const percentage = (score / 1000) * 100
|
||||||
|
|
||||||
|
// 统一使用蓝色渐变
|
||||||
|
return {
|
||||||
|
width: percentage + '%',
|
||||||
|
background: 'linear-gradient(90deg, #3b82f6 0%, #2563eb 100%)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进度条背景色样式
|
||||||
|
const getLevelBarBgStyle = (score) => {
|
||||||
|
// 统一使用淡蓝色背景
|
||||||
|
return {
|
||||||
|
background: '#eff6ff'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 评估描述
|
||||||
|
const getAssessmentDescription = (score) => {
|
||||||
|
if (score === -1) {
|
||||||
|
return '根据个人消费能力等级分析,无法获取该用户的消费能力信息,无法进行评估。'
|
||||||
|
}
|
||||||
|
|
||||||
|
const descriptions = {
|
||||||
|
100: '根据个人消费能力等级分析,该用户月消费能力较低,消费水平有限。',
|
||||||
|
200: '根据个人消费能力等级分析,该用户月消费能力较低,消费水平有限。',
|
||||||
|
300: '根据个人消费能力等级分析,该用户月消费能力中等,消费水平良好。',
|
||||||
|
400: '根据个人消费能力等级分析,该用户月消费能力中等,消费水平良好。',
|
||||||
|
500: '根据个人消费能力等级分析,该用户月消费能力中等偏上,消费水平较强。',
|
||||||
|
600: '根据个人消费能力等级分析,该用户月消费能力中等偏上,消费水平较强。',
|
||||||
|
700: '根据个人消费能力等级分析,该用户月消费能力较高,消费水平很强。',
|
||||||
|
800: '根据个人消费能力等级分析,该用户月消费能力较高,消费水平很强。',
|
||||||
|
900: '根据个人消费能力等级分析,该用户月消费能力很高,消费水平顶级。',
|
||||||
|
1000: '根据个人消费能力等级分析,该用户月消费能力很高,消费水平顶级。'
|
||||||
|
}
|
||||||
|
return descriptions[score] || '数据异常,无法进行准确评估。'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 市场对比分析
|
||||||
|
const getMarketComparison = (score) => {
|
||||||
|
if (score === -1) {
|
||||||
|
return '无消费能力信息,无法与市场平均水平进行对比。'
|
||||||
|
}
|
||||||
|
|
||||||
|
const comparisons = {
|
||||||
|
100: '低于市场平均消费水平,处于消费分布的底部区间。',
|
||||||
|
200: '低于市场平均消费水平,处于消费分布的中下区间。',
|
||||||
|
300: '接近市场平均消费水平,处于消费分布的中等区间。',
|
||||||
|
400: '接近市场平均消费水平,处于消费分布的中等区间。',
|
||||||
|
500: '高于市场平均消费水平,处于消费分布的中上区间。',
|
||||||
|
600: '高于市场平均消费水平,处于消费分布的中上区间。',
|
||||||
|
700: '明显高于市场平均消费水平,处于消费分布的上层区间。',
|
||||||
|
800: '显著高于市场平均消费水平,处于消费分布的高层区间。',
|
||||||
|
900: '远高于市场平均消费水平,处于消费分布的顶部区间。',
|
||||||
|
1000: '超越市场绝大多数消费水平,处于消费分布的顶级区间。'
|
||||||
|
}
|
||||||
|
return comparisons[score] || '数据异常,无法进行市场对比。'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 消费能力分析
|
||||||
|
const getConsumptionCapacity = (score) => {
|
||||||
|
if (score === -1) {
|
||||||
|
return '缺乏消费能力信息,月消费能力存在不确定性,需要谨慎评估。'
|
||||||
|
}
|
||||||
|
|
||||||
|
const capacities = {
|
||||||
|
100: '月消费能力较低,消费水平有限,建议理性消费。',
|
||||||
|
200: '月消费能力较低,消费水平有限,建议理性消费。',
|
||||||
|
300: '月消费能力稳定,消费水平良好,具备一定的消费潜力。',
|
||||||
|
400: '月消费能力稳定,消费水平良好,具备一定的消费潜力。',
|
||||||
|
500: '月消费能力较高,消费水平较强,可以支持中等消费。',
|
||||||
|
600: '月消费能力较高,消费水平较强,可以支持中等消费。',
|
||||||
|
700: '月消费能力很强,消费水平很高,可以支持较高消费。',
|
||||||
|
800: '月消费能力很强,消费水平很高,可以支持较高消费。',
|
||||||
|
900: '月消费能力顶级,消费水平极高,可以支持高端消费。',
|
||||||
|
1000: '月消费能力顶级,消费水平极高,可以支持顶级消费。'
|
||||||
|
}
|
||||||
|
return capacities[score] || '数据异常,无法进行消费能力分析。'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 指示器样式
|
||||||
|
const getIndicatorStyle = (score) => {
|
||||||
|
if (score === -1) return { width: '0%', background: 'transparent' }
|
||||||
|
|
||||||
|
// 100分=0%, 1000分=100%
|
||||||
|
const percentage = ((score - 100) / 900) * 100
|
||||||
|
return {
|
||||||
|
width: percentage + '%',
|
||||||
|
background: `linear-gradient(90deg, #93c5fd 0%, #3b82f6 50%, #1d4ed8 100%)`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标记位置
|
||||||
|
const getMarkerPosition = (score) => {
|
||||||
|
if (score === -1) return { left: '0%' }
|
||||||
|
|
||||||
|
// 100分=0%, 1000分=100%
|
||||||
|
const percentage = ((score - 100) / 900) * 100
|
||||||
|
return {
|
||||||
|
left: percentage + '%'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算风险评分(0-100分,分数越高越安全)
|
||||||
|
const riskScore = computed(() => {
|
||||||
|
if (score.value === -1) return 30 // 未命中,风险较高
|
||||||
|
// 100分对应30分,1000分对应100分
|
||||||
|
return 30 + ((score.value - 100) / 900) * 70
|
||||||
|
});
|
||||||
|
|
||||||
|
// 使用 composable 通知父组件风险评分
|
||||||
|
useRiskNotifier(props, riskScore);
|
||||||
|
|
||||||
|
// 暴露给父组件
|
||||||
|
defineExpose({
|
||||||
|
riskScore
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 金额数字样式 */
|
||||||
|
.amount-number {
|
||||||
|
color: #333333;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.amount-unit {
|
||||||
|
font-size: 0.5em;
|
||||||
|
color: #999999;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 进度条 */
|
||||||
|
.level-bar {
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-fill {
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.6s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 评估卡片 */
|
||||||
|
.assessment-card {
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 评估卡片统一样式 */
|
||||||
|
.assessment-card {
|
||||||
|
background: #f8fafc;
|
||||||
|
border-color: #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 对比指示器 */
|
||||||
|
.comparison-indicator {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.indicator-bar {
|
||||||
|
position: relative;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
background: linear-gradient(90deg, #93c5fd 0%, #3b82f6 50%, #1d4ed8 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.indicator-fill {
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.indicator-marker {
|
||||||
|
position: absolute;
|
||||||
|
top: -26px;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marker-image {
|
||||||
|
width: 24px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marker-dot {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0px 4px 4px 0px #00000040;
|
||||||
|
}
|
||||||
|
|
||||||
|
.indicator-labels {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -13,8 +13,16 @@
|
|||||||
<div class="text-sm mb-2" style="color: var(--van-text-color-2);">
|
<div class="text-sm mb-2" style="color: var(--van-text-color-2);">
|
||||||
累计收益:¥ {{ (data?.total_earnings || 0).toFixed(2) }}
|
累计收益:¥ {{ (data?.total_earnings || 0).toFixed(2) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm mb-6" style="color: var(--van-text-color-2);">
|
<div class="text-sm mb-6 flex items-center" style="color: var(--van-text-color-2);">
|
||||||
冻结余额:¥ {{ (data?.frozen_balance || 0).toFixed(2) }}
|
待结账金额:¥ {{ (data?.frozen_balance || 0).toFixed(2) }}
|
||||||
|
<van-popover v-model:show="showTooltip" placement="bottom-start" :offset="10">
|
||||||
|
<template #reference>
|
||||||
|
<van-icon name="question-o" class="ml-2 cursor-help" @mouseenter="showTooltip = true" @mouseleave="showTooltip = false" />
|
||||||
|
</template>
|
||||||
|
<div class="p-2 text-sm" style="max-width: 200px;">
|
||||||
|
待结账金额将在订单创建24小时后自动结账。
|
||||||
|
</div>
|
||||||
|
</van-popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3">
|
||||||
<button @click="toWithdraw"
|
<button @click="toWithdraw"
|
||||||
@@ -207,6 +215,7 @@ const agentStore = useAgentStore();
|
|||||||
const { isAgent } = storeToRefs(agentStore);
|
const { isAgent } = storeToRefs(agentStore);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const data = ref(null);
|
const data = ref(null);
|
||||||
|
const showTooltip = ref(false);
|
||||||
|
|
||||||
// 日期选项映射
|
// 日期选项映射
|
||||||
const dateRangeMap = {
|
const dateRangeMap = {
|
||||||
|
|||||||
@@ -5,20 +5,33 @@
|
|||||||
<div v-for="(item, index) in data.list" :key="index" class="mx-4 my-2 bg-white rounded-lg p-4 shadow-sm">
|
<div v-for="(item, index) in data.list" :key="index" class="mx-4 my-2 bg-white rounded-lg p-4 shadow-sm">
|
||||||
<div class="flex justify-between items-center mb-2">
|
<div class="flex justify-between items-center mb-2">
|
||||||
<!-- 修改点 1: 使用 desen 函数处理 mobile -->
|
<!-- 修改点 1: 使用 desen 函数处理 mobile -->
|
||||||
<span class="text-gray-500 text-sm">{{ desen(item.query_params.mobile, 'mobile') || '-' }}</span>
|
<span class="text-gray-500 text-sm">{{ desen(item.query_params?.mobile, 'mobile') || '-' }}</span>
|
||||||
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium"
|
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium"
|
||||||
:class="getReportTypeStyle(item.product_name)">
|
:class="getReportTypeStyle(item.product_name)">
|
||||||
<span class="w-2 h-2 rounded-full mr-1" :class="getDotColor(item.product_name)"></span>
|
<span class="w-2 h-2 rounded-full mr-1" :class="getDotColor(item.product_name)"></span>
|
||||||
{{ item.product_name }}
|
{{ item.product_name }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center justify-between mb-2">
|
||||||
<h4>直接收益</h4>
|
<h4 class="text-gray-700 font-medium">直接收益</h4>
|
||||||
<span class="text-green-500 font-bold">+{{ item.amount.toFixed(2) }}</span>
|
<div class="flex flex-col items-end">
|
||||||
|
<!-- 主金额:显示净佣金 -->
|
||||||
|
<span :class="getAmountColor(item)" class="font-bold text-lg">
|
||||||
|
{{ getAmountPrefix(item) }}{{ (item.net_amount || 0).toFixed(2) }}
|
||||||
|
</span>
|
||||||
|
<!-- 如果有部分退款,显示原始金额和已退金额 -->
|
||||||
|
<span v-if="item.refunded_amount > 0 && item.net_amount > 0" class="text-gray-400 text-xs mt-1">
|
||||||
|
原始 {{ item.amount.toFixed(2) }},已退 {{ item.refunded_amount.toFixed(2) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center justify-between">
|
||||||
<!-- 修改点 2: 使用 desen 函数处理 name -->
|
<span class="text-gray-500 text-sm">{{ desen(item.query_params?.name) || '-' }}</span>
|
||||||
<span class="text-gray-500 text-sm">{{ desen(item.query_params.name) || '-' }}</span>
|
<!-- 状态标签 -->
|
||||||
|
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium"
|
||||||
|
:class="getStatusStyle(item)">
|
||||||
|
{{ getStatusText(item) }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-center mb-2">
|
<div class="flex justify-between items-center mb-2">
|
||||||
<span class="text-gray-500 text-sm">{{ item.create_time || '-' }}</span>
|
<span class="text-gray-500 text-sm">{{ item.create_time || '-' }}</span>
|
||||||
@@ -85,6 +98,72 @@ const getDotColor = (name) => {
|
|||||||
return (typeColors[name] || typeColors.default).dot
|
return (typeColors[name] || typeColors.default).dot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取金额颜色
|
||||||
|
const getAmountColor = (item) => {
|
||||||
|
// 如果净佣金为0或状态为已退款,显示红色
|
||||||
|
if (item.net_amount <= 0 || item.status === 2) {
|
||||||
|
return 'text-red-500'
|
||||||
|
}
|
||||||
|
// 如果有部分退款,显示橙色
|
||||||
|
if (item.refunded_amount > 0) {
|
||||||
|
return 'text-orange-500'
|
||||||
|
}
|
||||||
|
// 正常情况显示绿色
|
||||||
|
return 'text-green-500'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取金额前缀(+ 或 -)
|
||||||
|
const getAmountPrefix = (item) => {
|
||||||
|
if (item.net_amount <= 0 || item.status === 2) {
|
||||||
|
return '-'
|
||||||
|
}
|
||||||
|
return '+'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态文本
|
||||||
|
const getStatusText = (item) => {
|
||||||
|
if (item.status === 2 || item.net_amount <= 0) {
|
||||||
|
return '已退款'
|
||||||
|
}
|
||||||
|
if (item.status === 1) {
|
||||||
|
// 冻结中
|
||||||
|
if (item.refunded_amount > 0) {
|
||||||
|
return '冻结中(部分退款)'
|
||||||
|
}
|
||||||
|
return '冻结中'
|
||||||
|
}
|
||||||
|
if (item.status === 0) {
|
||||||
|
// 已结算
|
||||||
|
if (item.refunded_amount > 0) {
|
||||||
|
return '已结算(部分退款)'
|
||||||
|
}
|
||||||
|
return '已结算'
|
||||||
|
}
|
||||||
|
return '未知状态'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态样式
|
||||||
|
const getStatusStyle = (item) => {
|
||||||
|
if (item.status === 2 || item.net_amount <= 0) {
|
||||||
|
return 'bg-red-100 text-red-800'
|
||||||
|
}
|
||||||
|
if (item.status === 1) {
|
||||||
|
// 冻结中
|
||||||
|
if (item.refunded_amount > 0) {
|
||||||
|
return 'bg-orange-100 text-orange-800'
|
||||||
|
}
|
||||||
|
return 'bg-yellow-100 text-yellow-800'
|
||||||
|
}
|
||||||
|
if (item.status === 0) {
|
||||||
|
// 已结算
|
||||||
|
if (item.refunded_amount > 0) {
|
||||||
|
return 'bg-blue-100 text-blue-800'
|
||||||
|
}
|
||||||
|
return 'bg-green-100 text-green-800'
|
||||||
|
}
|
||||||
|
return 'bg-gray-100 text-gray-800'
|
||||||
|
}
|
||||||
|
|
||||||
// 加载更多数据
|
// 加载更多数据
|
||||||
const onLoad = async () => {
|
const onLoad = async () => {
|
||||||
if (!finished.value) {
|
if (!finished.value) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const featureData = ref({});
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
isFinishPayment();
|
isFinishPayment();
|
||||||
await getProduct();
|
await getProduct();
|
||||||
|
// 检查是否为婚姻查询页面,如果是则显示升级通知
|
||||||
});
|
});
|
||||||
|
|
||||||
function isFinishPayment() {
|
function isFinishPayment() {
|
||||||
@@ -22,6 +23,98 @@ function isFinishPayment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 婚姻查询升级通知弹窗
|
||||||
|
function showMarriageUpgradeNotice() {
|
||||||
|
// 创建自定义弹窗
|
||||||
|
const modal = document.createElement('div');
|
||||||
|
modal.style.position = 'fixed';
|
||||||
|
modal.style.top = '0';
|
||||||
|
modal.style.left = '0';
|
||||||
|
modal.style.width = '100%';
|
||||||
|
modal.style.height = '100%';
|
||||||
|
modal.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
|
||||||
|
modal.style.display = 'flex';
|
||||||
|
modal.style.justifyContent = 'center';
|
||||||
|
modal.style.alignItems = 'center';
|
||||||
|
modal.style.zIndex = '9999';
|
||||||
|
|
||||||
|
modal.innerHTML = `
|
||||||
|
<div style="
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 24px;
|
||||||
|
margin: 20px;
|
||||||
|
max-width: 400px;
|
||||||
|
width: 90%;
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||||
|
position: relative;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 90vh;
|
||||||
|
">
|
||||||
|
<h3 style="
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-size: 18px;
|
||||||
|
">亲爱的用户,您好!</h3>
|
||||||
|
|
||||||
|
<p style="
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin: 8px 0;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
">婚恋报告正在优化升级中,需要查询请前往天远查。</p>
|
||||||
|
|
||||||
|
|
||||||
|
<div style="display: flex; gap: 12px; margin-bottom: 16px;">
|
||||||
|
<button id="jumpNowBtn" style="
|
||||||
|
flex: 1;
|
||||||
|
background: linear-gradient(135deg, #ff6b6b, #ee5a24);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-radius: 25px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
">是</button>
|
||||||
|
|
||||||
|
<button id="remindLaterBtn" style="
|
||||||
|
flex: 1;
|
||||||
|
background: #f8f9fa;
|
||||||
|
color: #666;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-radius: 25px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
">否</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
|
||||||
|
// 绑定按钮事件
|
||||||
|
const jumpNowBtn = modal.querySelector('#jumpNowBtn');
|
||||||
|
const remindLaterBtn = modal.querySelector('#remindLaterBtn');
|
||||||
|
|
||||||
|
jumpNowBtn.addEventListener('click', () => {
|
||||||
|
// 跳转到新版首页
|
||||||
|
window.open('https://www.tianyuancha.cn/', '_blank');
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
});
|
||||||
|
|
||||||
|
remindLaterBtn.addEventListener('click', () => {
|
||||||
|
// 跳转到指定网站
|
||||||
|
window.location.href = 'https://www.tianyuandb.com/';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function getProduct() {
|
async function getProduct() {
|
||||||
const { data, error } = await useApiFetch(`/product/en/${feature.value}`)
|
const { data, error } = await useApiFetch(`/product/en/${feature.value}`)
|
||||||
.get()
|
.get()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { ref, computed, onUnmounted, nextTick } from 'vue'
|
import { ref, computed, onUnmounted, nextTick } from 'vue'
|
||||||
import { showToast } from 'vant'
|
import { showToast } from 'vant'
|
||||||
import ClickCaptcha from '@/components/ClickCaptcha.vue'
|
import ClickCaptcha from '@/components/ClickCaptcha.vue'
|
||||||
|
import { useAliyunCaptcha } from "@/composables/useAliyunCaptcha";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const phoneNumber = ref('')
|
const phoneNumber = ref('')
|
||||||
@@ -13,6 +14,8 @@ const isCountingDown = ref(false)
|
|||||||
const countdown = ref(60)
|
const countdown = ref(60)
|
||||||
let timer = null
|
let timer = null
|
||||||
|
|
||||||
|
const { runWithCaptcha } = useAliyunCaptcha();
|
||||||
|
|
||||||
// 验证组件状态
|
// 验证组件状态
|
||||||
const showCaptcha = ref(false)
|
const showCaptcha = ref(false)
|
||||||
const captchaVerified = ref(false)
|
const captchaVerified = ref(false)
|
||||||
@@ -41,25 +44,26 @@ async function sendVerificationCode() {
|
|||||||
showToast({ message: "请输入有效的手机号" });
|
showToast({ message: "请输入有效的手机号" });
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { data, error } = await useApiFetch('auth/sendSms')
|
await runWithCaptcha(
|
||||||
.post({ mobile: phoneNumber.value, actionType: 'login' })
|
(captchaVerifyParam) =>
|
||||||
.json()
|
useApiFetch('auth/sendSms')
|
||||||
|
.post({ mobile: phoneNumber.value, actionType: 'login', captchaVerifyParam })
|
||||||
if (data.value && !error.value) {
|
.json(),
|
||||||
if (data.value.code === 200) {
|
(res) => {
|
||||||
showToast({ message: "获取成功" });
|
if (res.code === 200) {
|
||||||
startCountdown()
|
showToast({ message: "获取成功" });
|
||||||
// 聚焦到验证码输入框
|
startCountdown();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const verificationCodeInput = document.getElementById('verificationCode');
|
const verificationCodeInput = document.getElementById('verificationCode');
|
||||||
if (verificationCodeInput) {
|
if (verificationCodeInput) {
|
||||||
verificationCodeInput.focus();
|
verificationCodeInput.focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
showToast(data.value.msg)
|
showToast({ message: res.msg || "发送失败" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function startCountdown() {
|
function startCountdown() {
|
||||||
@@ -151,7 +155,7 @@ const onClickLeft = () => {
|
|||||||
<div class="login px-4 relative z-10">
|
<div class="login px-4 relative z-10">
|
||||||
<div class="mb-8 pt-20 text-left">
|
<div class="mb-8 pt-20 text-left">
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<img class="h-16 w-16 rounded-full shadow" src="/logo.jpg" alt="Logo" />
|
<img class="h-16 w-16 rounded-full shadow" src="/logo.png" alt="Logo" />
|
||||||
<div class="text-3xl mt-4 text-slate-700 font-bold">天远数据</div>
|
<div class="text-3xl mt-4 text-slate-700 font-bold">天远数据</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ onMounted(() => {
|
|||||||
title: '404 - 页面未找到 | 天远数据',
|
title: '404 - 页面未找到 | 天远数据',
|
||||||
description: '抱歉,您访问的页面不存在。天远数据专业大数据风险管控平台,提供大数据风险报告查询、婚姻状况查询、个人信用评估等服务。',
|
description: '抱歉,您访问的页面不存在。天远数据专业大数据风险管控平台,提供大数据风险报告查询、婚姻状况查询、个人信用评估等服务。',
|
||||||
keywords: '404, 页面未找到, 天远数据, 大数据风险管控',
|
keywords: '404, 页面未找到, 天远数据, 大数据风险管控',
|
||||||
url: 'https://www.zhinengcha.cn/404'
|
url: 'https://www.tianyuandb.com/404'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ const reportTypes = [
|
|||||||
{ text: "个人大数据", value: "personaldata", id: 27 },
|
{ text: "个人大数据", value: "personaldata", id: 27 },
|
||||||
{ text: '入职风险', value: 'backgroundcheck', id: 1 },
|
{ text: '入职风险', value: 'backgroundcheck', id: 1 },
|
||||||
{ text: '家政风险', value: 'homeservice', id: 3 },
|
{ text: '家政风险', value: 'homeservice', id: 3 },
|
||||||
// { text: '婚恋风险', value: 'marriage', id: 4 },
|
{ text: '婚恋风险', value: 'marriage', id: 4 },
|
||||||
// { text: '租赁风险', value: 'rentalrisk', id: 6 },
|
{ text: '租赁风险', value: 'rentalrisk', id: 6 },
|
||||||
|
|
||||||
];
|
];
|
||||||
const showTypePicker = ref(false);
|
const showTypePicker = ref(false);
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ import { ref, onMounted, onBeforeMount } from "vue";
|
|||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useUserStore } from '@/stores/userStore';
|
import { useUserStore } from '@/stores/userStore';
|
||||||
|
import { useDialogStore } from '@/stores/dialogStore';
|
||||||
import InquireForm from "@/components/InquireForm.vue";
|
import InquireForm from "@/components/InquireForm.vue";
|
||||||
|
import LoginDialog from "@/components/LoginDialog.vue";
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const dialogStore = useDialogStore();
|
||||||
const { mobile: userStoreMobile } = storeToRefs(userStore);
|
const { mobile: userStoreMobile } = storeToRefs(userStore);
|
||||||
|
|
||||||
const linkIdentifier = ref("");
|
const linkIdentifier = ref("");
|
||||||
@@ -59,4 +62,5 @@ async function getProduct() {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<InquireForm :type="'promotion'" :feature="feature" :link-identifier="linkIdentifier" :feature-data="featureData" />
|
<InquireForm :type="'promotion'" :feature="feature" :link-identifier="linkIdentifier" :feature-data="featureData" />
|
||||||
|
<LoginDialog />
|
||||||
</template>
|
</template>
|
||||||
@@ -430,7 +430,7 @@ const dialogStore = useDialogStore();
|
|||||||
// - 'bankcard': 只显示银行卡提现
|
// - 'bankcard': 只显示银行卡提现
|
||||||
// - 'both': 显示两种提现方式(默认)
|
// - 'both': 显示两种提现方式(默认)
|
||||||
// - 数组形式: ['alipay', 'bankcard'] 或 ['alipay'] 或 ['bankcard']
|
// - 数组形式: ['alipay', 'bankcard'] 或 ['alipay'] 或 ['bankcard']
|
||||||
const WITHDRAW_CONFIG = import.meta.env.VITE_WITHDRAW_METHODS || 'bankcard';
|
const WITHDRAW_CONFIG = import.meta.env.VITE_WITHDRAW_METHODS || ['alipay', 'bankcard'];
|
||||||
// 解析配置:支持字符串和数组格式
|
// 解析配置:支持字符串和数组格式
|
||||||
const getWithdrawMethods = () => {
|
const getWithdrawMethods = () => {
|
||||||
if (Array.isArray(WITHDRAW_CONFIG)) {
|
if (Array.isArray(WITHDRAW_CONFIG)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user