907 lines
29 KiB
Vue
907 lines
29 KiB
Vue
<template>
|
||
<div class="contract-case-page">
|
||
<div class="decor decor--blue" />
|
||
<div class="decor decor--purple" />
|
||
|
||
<section class="case-hero" :style="{ backgroundImage: `url(${bannerImg})` }">
|
||
<div class="case-container">
|
||
<div class="case-hero__content">
|
||
<h1>{{ $t('casePages.contract.heroTitle') }}</h1>
|
||
<p>
|
||
{{ $t('casePages.contract.heroDesc') }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="case-tabs">
|
||
<div class="case-container">
|
||
<button
|
||
v-for="tab in localizedTabs"
|
||
:key="tab.id"
|
||
type="button"
|
||
class="tab-item"
|
||
:class="{ 'tab-active': activeTab === tab.id }"
|
||
@click="scrollToSection(tab.id)"
|
||
>
|
||
{{ tab.label }}
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<main class="case-main">
|
||
<section id="scenarios" class="case-section">
|
||
<div class="case-container">
|
||
<div class="section-heading">
|
||
<h2>{{ $t('casePages.contract.scenariosTitle') }}</h2>
|
||
<p>{{ $t('casePages.contract.scenariosDesc') }}</p>
|
||
</div>
|
||
<div class="case-scenario-grid">
|
||
<article class="case-feature-card scenario-card">
|
||
<div class="case-feature-card__visual case-feature-card__visual--illustration visual-blue">
|
||
<svg viewBox="0 0 400 200" fill="none">
|
||
<circle cx="320" cy="40" r="60" fill="#3b82f6" opacity="0.1" />
|
||
<circle cx="80" cy="160" r="40" fill="#6366f1" opacity="0.1" />
|
||
<g transform="translate(120, 40)">
|
||
<rect x="0" y="20" width="120" height="140" rx="8" fill="#e0e7ff" stroke="#3b82f6" stroke-width="2" />
|
||
<line x1="20" y1="45" x2="100" y2="45" stroke="#3b82f6" stroke-width="2" opacity="0.3" />
|
||
<line x1="20" y1="65" x2="100" y2="65" stroke="#3b82f6" stroke-width="2" opacity="0.3" />
|
||
<line x1="20" y1="85" x2="80" y2="85" stroke="#3b82f6" stroke-width="2" opacity="0.3" />
|
||
<rect x="15" y="10" width="120" height="140" rx="8" fill="#c7d2fe" stroke="#3b82f6" stroke-width="2" />
|
||
<line x1="35" y1="35" x2="115" y2="35" stroke="#3b82f6" stroke-width="2" opacity="0.5" />
|
||
<line x1="35" y1="55" x2="115" y2="55" stroke="#3b82f6" stroke-width="2" opacity="0.5" />
|
||
<line x1="35" y1="75" x2="95" y2="75" stroke="#3b82f6" stroke-width="2" opacity="0.5" />
|
||
<rect x="30" y="0" width="120" height="140" rx="8" fill="white" stroke="#3b82f6" stroke-width="2" />
|
||
<line x1="50" y1="25" x2="130" y2="25" stroke="#3b82f6" stroke-width="2" />
|
||
<line x1="50" y1="45" x2="130" y2="45" stroke="#3b82f6" stroke-width="2" />
|
||
<line x1="50" y1="65" x2="110" y2="65" stroke="#3b82f6" stroke-width="2" />
|
||
<circle cx="135" cy="25" r="8" fill="#10b981" />
|
||
<path d="M 131 25 L 134 28 L 139 22" stroke="white" stroke-width="2" stroke-linecap="round" />
|
||
<circle cx="135" cy="45" r="8" fill="#10b981" />
|
||
<path d="M 131 45 L 134 48 L 139 42" stroke="white" stroke-width="2" stroke-linecap="round" />
|
||
<circle cx="135" cy="65" r="8" fill="#f59e0b" />
|
||
<line x1="131" y1="65" x2="139" y2="65" stroke="white" stroke-width="2" stroke-linecap="round" />
|
||
</g>
|
||
<g class="magnifier" transform="translate(60, 60)">
|
||
<circle cx="25" cy="25" r="20" fill="none" stroke="#3b82f6" stroke-width="3" />
|
||
<line x1="40" y1="40" x2="55" y2="55" stroke="#3b82f6" stroke-width="4" stroke-linecap="round" />
|
||
<circle cx="25" cy="25" r="12" fill="#3b82f6" opacity="0.1" />
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
<div class="case-feature-card__head">
|
||
<span class="case-icon-gradient">
|
||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z" />
|
||
</svg>
|
||
</span>
|
||
<h3>{{ $t('casePages.contract.scenarios.0.title') }}</h3>
|
||
</div>
|
||
<p>{{ $t('casePages.contract.scenarios.0.desc') }}</p>
|
||
</article>
|
||
|
||
<article class="case-feature-card scenario-card">
|
||
<div class="case-feature-card__visual case-feature-card__visual--illustration visual-purple">
|
||
<svg viewBox="0 0 400 200" fill="none">
|
||
<circle cx="100" cy="50" r="50" fill="#8b5cf6" opacity="0.1" />
|
||
<circle cx="300" cy="150" r="60" fill="#ec4899" opacity="0.1" />
|
||
<g transform="translate(140, 30)">
|
||
<path d="M 60 0 L 120 20 L 120 80 Q 120 120 60 140 Q 0 120 0 80 L 0 20 Z" fill="#ddd6fe" stroke="#8b5cf6" stroke-width="2" opacity="0.6" />
|
||
<path d="M 60 15 L 105 30 L 105 75 Q 105 105 60 120 Q 15 105 15 75 L 15 30 Z" fill="#c4b5fd" stroke="#8b5cf6" stroke-width="2" opacity="0.8" />
|
||
<path d="M 60 30 L 90 40 L 90 70 Q 90 90 60 100 Q 30 90 30 70 L 30 40 Z" fill="white" stroke="#8b5cf6" stroke-width="2" />
|
||
<rect x="48" y="55" width="24" height="20" rx="2" fill="#8b5cf6" />
|
||
<path d="M 52 55 L 52 48 Q 52 42 60 42 Q 68 42 68 48 L 68 55" fill="none" stroke="#8b5cf6" stroke-width="3" />
|
||
<circle cx="60" cy="65" r="3" fill="white" />
|
||
</g>
|
||
<g class="risk-dots">
|
||
<circle cx="80" cy="100" r="6" fill="#ef4444" />
|
||
<circle cx="80" cy="100" r="10" fill="#ef4444" opacity="0.3" />
|
||
<circle cx="320" cy="80" r="6" fill="#f59e0b" />
|
||
<circle cx="320" cy="80" r="10" fill="#f59e0b" opacity="0.3" />
|
||
<circle cx="280" cy="140" r="6" fill="#10b981" />
|
||
<circle cx="280" cy="140" r="10" fill="#10b981" opacity="0.3" />
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
<div class="case-feature-card__head">
|
||
<span class="case-icon-gradient">
|
||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||
</svg>
|
||
</span>
|
||
<h3>{{ $t('casePages.contract.scenarios.1.title') }}</h3>
|
||
</div>
|
||
<p>{{ $t('casePages.contract.scenarios.1.desc') }}</p>
|
||
</article>
|
||
|
||
<article class="case-feature-card scenario-card">
|
||
<div class="case-feature-card__visual case-feature-card__visual--illustration visual-green">
|
||
<svg viewBox="0 0 400 200" fill="none">
|
||
<circle cx="350" cy="60" r="50" fill="#10b981" opacity="0.1" />
|
||
<circle cx="50" cy="140" r="40" fill="#14b8a6" opacity="0.1" />
|
||
<g transform="translate(80, 40)">
|
||
<rect x="0" y="0" width="100" height="130" rx="6" fill="white" stroke="#10b981" stroke-width="2" />
|
||
<text x="10" y="20" font-size="10" fill="#10b981" font-weight="bold">V1.0</text>
|
||
<line x1="15" y1="35" x2="85" y2="35" stroke="#10b981" stroke-width="1.5" opacity="0.5" />
|
||
<line x1="15" y1="50" x2="85" y2="50" stroke="#10b981" stroke-width="1.5" opacity="0.5" />
|
||
<line x1="15" y1="65" x2="75" y2="65" stroke="#10b981" stroke-width="1.5" opacity="0.5" />
|
||
<line x1="15" y1="80" x2="85" y2="80" stroke="#10b981" stroke-width="1.5" opacity="0.5" />
|
||
<line x1="15" y1="95" x2="65" y2="95" stroke="#10b981" stroke-width="1.5" opacity="0.5" />
|
||
<line x1="15" y1="50" x2="85" y2="50" stroke="#ef4444" stroke-width="2" />
|
||
</g>
|
||
<g transform="translate(220, 40)">
|
||
<rect x="0" y="0" width="100" height="130" rx="6" fill="white" stroke="#14b8a6" stroke-width="2" />
|
||
<text x="10" y="20" font-size="10" fill="#14b8a6" font-weight="bold">V2.0</text>
|
||
<line x1="15" y1="35" x2="85" y2="35" stroke="#14b8a6" stroke-width="1.5" opacity="0.5" />
|
||
<line x1="15" y1="50" x2="85" y2="50" stroke="#14b8a6" stroke-width="1.5" opacity="0.5" />
|
||
<line x1="15" y1="65" x2="85" y2="65" stroke="#14b8a6" stroke-width="1.5" opacity="0.5" />
|
||
<line x1="15" y1="80" x2="75" y2="80" stroke="#14b8a6" stroke-width="1.5" opacity="0.5" />
|
||
<line x1="15" y1="95" x2="85" y2="95" stroke="#14b8a6" stroke-width="1.5" opacity="0.5" />
|
||
<rect x="13" y="63" width="74" height="4" fill="#10b981" opacity="0.3" />
|
||
</g>
|
||
<g class="compare-arrow" transform="translate(185, 90)">
|
||
<path d="M 0 15 L 20 15 M 15 10 L 20 15 L 15 20" stroke="#6366f1" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" />
|
||
</g>
|
||
<g class="diff-tags">
|
||
<rect x="90" y="48" width="30" height="8" rx="2" fill="#ef4444" opacity="0.2" />
|
||
<text x="95" y="54" font-size="8" fill="#ef4444" font-weight="bold">{{ $t('casePages.contract.deleted') || '删除' }}</text>
|
||
<rect x="230" y="63" width="30" height="8" rx="2" fill="#10b981" opacity="0.2" />
|
||
<text x="235" y="69" font-size="8" fill="#10b981" font-weight="bold">{{ $t('casePages.contract.added') || '新增' }}</text>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
<div class="case-feature-card__head">
|
||
<span class="case-icon-gradient">
|
||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
|
||
</svg>
|
||
</span>
|
||
<h3>{{ $t('casePages.contract.scenarios.2.title') }}</h3>
|
||
</div>
|
||
<p>{{ $t('casePages.contract.scenarios.2.desc') }}</p>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="solution" class="case-section solution-section">
|
||
<div class="case-container">
|
||
<div class="section-heading">
|
||
<h2>{{ $t('casePages.contract.solutionTitle') }}</h2>
|
||
<p>{{ $t('casePages.contract.solutionDesc') }}</p>
|
||
</div>
|
||
<div class="solution-grid">
|
||
<div class="solution-column">
|
||
<div class="column-title column-title--danger">
|
||
<span>
|
||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01M4.93 19h14.14c1.54 0 2.5-1.67 1.73-3L13.73 4c-.77-1.33-2.69-1.33-3.46 0L3.2 16c-.77 1.33.19 3 1.73 3z" />
|
||
</svg>
|
||
</span>
|
||
<h3>{{ $t('casePages.contract.challengeTitle') }}</h3>
|
||
</div>
|
||
<article v-for="item in localizedProblems" :key="item.title" class="solution-item solution-item--danger">
|
||
<span class="solution-icon">
|
||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" :d="item.icon" />
|
||
</svg>
|
||
</span>
|
||
<div>
|
||
<h4>{{ item.title }}</h4>
|
||
<p>{{ item.desc }}</p>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
|
||
<div class="solution-column">
|
||
<div class="column-title column-title--primary">
|
||
<span>
|
||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||
</svg>
|
||
</span>
|
||
<h3>{{ $t('casePages.contract.abilityTitle') }}</h3>
|
||
</div>
|
||
<article v-for="item in localizedSolutions" :key="item.title" class="solution-item solution-item--primary">
|
||
<span class="solution-icon">
|
||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" :d="item.icon" />
|
||
</svg>
|
||
</span>
|
||
<div>
|
||
<h4>{{ item.title }}</h4>
|
||
<p>{{ item.desc }}</p>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="highlights" class="case-section">
|
||
<div class="case-container">
|
||
<div class="section-heading">
|
||
<h2>{{ $t('casePages.contract.highlightsTitle') }}</h2>
|
||
<p>{{ $t('casePages.contract.highlightsDesc') }}</p>
|
||
</div>
|
||
<div class="case-highlight-grid">
|
||
<article v-for="(item, index) in localizedHighlights" :key="item.title" class="case-highlight-card">
|
||
<span class="highlight-num">{{ index + 1 }}</span>
|
||
<div>
|
||
<h3>{{ item.title }}</h3>
|
||
<p>{{ item.desc }}</p>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'ContractCase',
|
||
data() {
|
||
return {
|
||
activeTab: 'scenarios',
|
||
bannerImg: require('@/assets/image/bgimg.png'),
|
||
tabs: [
|
||
{ id: 'scenarios', label: '应用场景' },
|
||
{ id: 'solution', label: '解决方案' },
|
||
{ id: 'highlights', label: '项目亮点' }
|
||
],
|
||
scenarios: [
|
||
{
|
||
title: '业务合同初审',
|
||
desc: '自动解析购销、服务、租赁、合作类通用业务合同,逐条对标企业风控红线快速筛查风险点,输出初审意见,减轻法务基础审核工作量。',
|
||
icon: 'M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z',
|
||
visualClass: 'visual-blue'
|
||
},
|
||
{
|
||
title: '复杂商事合同深度风控',
|
||
desc: '针对投融资、知识产权、工程、保密竞业等高风险专项合同,联动完整法条与司法判例开展多层级风险推演,输出完整风控评估文档。',
|
||
icon: 'M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z',
|
||
visualClass: 'visual-purple'
|
||
},
|
||
{
|
||
title: '多方合同版本比对修订',
|
||
desc: '自动识别甲乙双方多轮修改稿件差异,区分新增、删减、修改条款,高亮标注风险变更内容,辅助商务谈判与法务复核。',
|
||
icon: 'M8 7h12m0 0l-4-4m4 4l-4 4M16 17H4m0 0l4 4m-4-4l4-4',
|
||
visualClass: 'visual-green'
|
||
}
|
||
],
|
||
problems: [
|
||
{
|
||
title: '文件信息割裂分散',
|
||
desc: '合同、法规、历史判例、内部模板散落在不同存储渠道,无统一检索入口,审核时需跨文件反复核对。',
|
||
icon: 'M4 7v10c0 2.21 3.58 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.58 4 8 4s8-1.79 8-4M4 7c0-2.21 3.58-4 8-4s8 1.79 8 4'
|
||
},
|
||
{
|
||
title: '风控经验难以留存复用',
|
||
desc: '资深法务的审查要点、谈判底线、风险处置经验仅存于个人,人员交接后容易出现标准不统一。',
|
||
icon: 'M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z'
|
||
},
|
||
{
|
||
title: '人工审核耗时长、标准化弱',
|
||
desc: '海量合同逐条人工审阅消耗大量人力,不同法务审核尺度参差不齐,紧急签约场景响应慢。',
|
||
icon: 'M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z'
|
||
}
|
||
],
|
||
solutions: [
|
||
{
|
||
title: '多源文件统一归集解析',
|
||
desc: '批量上传 PDF、Word、扫描件合同,OCR 识别图文内容,统一结构化抽取交易主体、价款、履约、违约等关键信息。',
|
||
icon: 'M4 7v10c0 2.21 3.58 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.58 4 8 4s8-1.79 8-4'
|
||
},
|
||
{
|
||
title: '全条款 AI 智能编审修正',
|
||
desc: '分层扫描合同全部条款,对标法律法规与企业内控规则标记高中低三级风险,配套标准化合规替换条款。',
|
||
icon: 'M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414A1 1 0 0119 9.414V19a2 2 0 01-2 2z'
|
||
},
|
||
{
|
||
title: '法务知识库沉淀管理',
|
||
desc: '将企业标准模板、审查清单、判例、内部风控制度转化为结构化知识库,沉淀企业专属法务资产。',
|
||
icon: 'M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253'
|
||
},
|
||
{
|
||
title: '自然语言法务智能问答',
|
||
desc: '支持业务、法务人员以口语化提问查询合规要求、条款写法、风险后果,即时输出专业解答与参考条款。',
|
||
icon: 'M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z'
|
||
}
|
||
],
|
||
highlights: [
|
||
{
|
||
title: '分级风险自动标注,配套合规整改条款',
|
||
desc: '按重大、一般、提示三级划分风险,精准定位风险对应原文段落,每条风险同步匹配适配企业制度与现行法律的替换条款。'
|
||
},
|
||
{
|
||
title: '多版本合同差异智能比对溯源',
|
||
desc: '上传新旧合同、甲乙双方往来稿件,系统自动高亮新增、删减、变更条款,生成可追溯对比台账。'
|
||
},
|
||
{
|
||
title: '全格式合同兼容识别,扫描件精准解析',
|
||
desc: '支持 Word、PDF、图片扫描件、盖章影像文件上传,内置高精度 OCR 图文识别,覆盖存量和增量合同文件。'
|
||
},
|
||
{
|
||
title: '企业法务知识一键复用,审查标准统一',
|
||
desc: '内置企业专属合同模板库、风控红线清单、行业判例库,新员工可直接复用成熟审查标准。'
|
||
}
|
||
]
|
||
}
|
||
},
|
||
computed: {
|
||
localizedTabs() {
|
||
return this.tabs.map(tab => ({
|
||
...tab,
|
||
label: this.$t(`casePages.contract.tabs.${tab.id}`)
|
||
}))
|
||
},
|
||
localizedProblems() {
|
||
return this.getLocalizedList(this.problems, 'casePages.contract.challenges')
|
||
},
|
||
localizedSolutions() {
|
||
return this.getLocalizedList(this.solutions, 'casePages.contract.abilities')
|
||
},
|
||
localizedHighlights() {
|
||
return this.getLocalizedList(this.highlights, 'casePages.contract.highlights')
|
||
}
|
||
},
|
||
mounted() {
|
||
this.$nextTick(() => {
|
||
const scroller = this.getScrollContainer()
|
||
this.resetScrollTop(scroller)
|
||
scroller.addEventListener('scroll', this.handlePageScroll, { passive: true })
|
||
this.handlePageScroll()
|
||
})
|
||
},
|
||
beforeDestroy() {
|
||
this.getScrollContainer().removeEventListener('scroll', this.handlePageScroll)
|
||
},
|
||
methods: {
|
||
getLocalizedList(list, keyPrefix) {
|
||
return list.map((item, index) => ({
|
||
...item,
|
||
title: this.$t(`${keyPrefix}.${index}.title`),
|
||
desc: this.$t(`${keyPrefix}.${index}.desc`)
|
||
}))
|
||
},
|
||
getScrollContainer() {
|
||
return document.getElementById('homeOut') || window
|
||
},
|
||
resetScrollTop(scroller) {
|
||
if (scroller === window) {
|
||
window.scrollTo(0, 0)
|
||
} else {
|
||
scroller.scrollTop = 0
|
||
}
|
||
},
|
||
getElementTopInScroller(element, scroller) {
|
||
if (scroller === window) {
|
||
return element.getBoundingClientRect().top + window.pageYOffset
|
||
}
|
||
return element.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop
|
||
},
|
||
getScrollerTop(scroller) {
|
||
return scroller === window ? window.pageYOffset : scroller.scrollTop
|
||
},
|
||
scrollToSection(sectionName) {
|
||
this.activeTab = sectionName
|
||
const element = this.$el.querySelector(`#${sectionName}`)
|
||
if (!element) return
|
||
const scroller = this.getScrollContainer()
|
||
const top = this.getElementTopInScroller(element, scroller)
|
||
scroller.scrollTo({ top, behavior: 'smooth' })
|
||
},
|
||
handlePageScroll() {
|
||
const scroller = this.getScrollContainer()
|
||
const scrollerTop = this.getScrollerTop(scroller)
|
||
const offsetTop = scrollerTop + 24
|
||
const currentTab = this.tabs
|
||
.map(tab => {
|
||
const element = this.$el.querySelector(`#${tab.id}`)
|
||
return element ? { id: tab.id, top: this.getElementTopInScroller(element, scroller) } : null
|
||
})
|
||
.filter(Boolean)
|
||
.reverse()
|
||
.find(tab => offsetTop >= tab.top)
|
||
if (currentTab) this.activeTab = currentTab.id
|
||
},
|
||
handleContact() {
|
||
this.$message.info('感谢您的关注,我们将尽快与您联系')
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.contract-case-page {
|
||
position: relative;
|
||
width: 100%;
|
||
min-height: 100vh;
|
||
overflow: visible;
|
||
color: #111827;
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
||
background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%);
|
||
}
|
||
|
||
.contract-case-page *,
|
||
.contract-case-page *::before,
|
||
.contract-case-page *::after {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.contract-case-page h1,
|
||
.contract-case-page h2,
|
||
.contract-case-page h3,
|
||
.contract-case-page h4,
|
||
.contract-case-page p {
|
||
margin-top: 0;
|
||
font-family: inherit;
|
||
}
|
||
|
||
.case-container {
|
||
width: 100%;
|
||
max-width: 1280px;
|
||
margin: 0 auto;
|
||
padding: 0 24px;
|
||
}
|
||
|
||
.decor {
|
||
position: absolute;
|
||
border-radius: 999px;
|
||
filter: blur(64px);
|
||
opacity: 0.12;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.decor--blue {
|
||
top: 80px;
|
||
left: 40px;
|
||
width: 256px;
|
||
height: 256px;
|
||
background: linear-gradient(135deg, #60a5fa, #a855f7);
|
||
}
|
||
|
||
.decor--purple {
|
||
top: 400px;
|
||
right: 80px;
|
||
width: 320px;
|
||
height: 320px;
|
||
background: linear-gradient(135deg, #c084fc, #3b82f6);
|
||
}
|
||
|
||
.case-hero {
|
||
position: relative;
|
||
min-height: min(446px, calc(100vw * 446 / 1551));
|
||
padding: 120px 0 86px;
|
||
overflow: hidden;
|
||
background-repeat: no-repeat;
|
||
background-position: center;
|
||
background-size: cover;
|
||
}
|
||
|
||
.case-hero__content {
|
||
max-width: 900px;
|
||
}
|
||
|
||
.case-hero h1 {
|
||
margin: 0 0 24px;
|
||
color: #111827;
|
||
font-size: 48px;
|
||
font-weight: 800;
|
||
line-height: 1.1;
|
||
}
|
||
|
||
.case-hero p {
|
||
max-width: 980px;
|
||
margin: 0;
|
||
color: #4b5563;
|
||
font-size: 20px;
|
||
line-height: 1.75;
|
||
}
|
||
|
||
.case-tabs {
|
||
height: 60px;
|
||
background: #fff;
|
||
border-bottom: 1px solid #e5e7eb;
|
||
box-shadow: 0 6px 18px rgba(15, 23, 42, 0.06);
|
||
}
|
||
|
||
.case-tabs .case-container {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 32px;
|
||
height: 100%;
|
||
}
|
||
|
||
.tab-item {
|
||
height: 100%;
|
||
padding: 12px 16px;
|
||
color: #374151;
|
||
font-weight: 500;
|
||
background: transparent;
|
||
border: 0;
|
||
border-radius: 8px;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.tab-item:hover,
|
||
.tab-active {
|
||
color: #3b82f6;
|
||
background: #eff6ff;
|
||
}
|
||
|
||
.case-main {
|
||
padding-bottom: 80px;
|
||
}
|
||
|
||
.case-section {
|
||
position: relative;
|
||
padding: 72px 0;
|
||
}
|
||
|
||
.solution-section {
|
||
background: linear-gradient(135deg, #f9fafb 0%, #eff6ff 100%);
|
||
}
|
||
|
||
.section-heading {
|
||
margin-bottom: 48px;
|
||
text-align: center;
|
||
}
|
||
|
||
.section-heading h2 {
|
||
margin: 0 0 16px;
|
||
color: #111827;
|
||
font-size: 40px;
|
||
font-weight: 800;
|
||
}
|
||
|
||
.section-heading p {
|
||
margin: 0;
|
||
color: #4b5563;
|
||
font-size: 20px;
|
||
}
|
||
|
||
.case-scenario-grid,
|
||
.solution-grid,
|
||
.case-highlight-grid {
|
||
display: grid;
|
||
gap: 32px;
|
||
}
|
||
|
||
.contract-case-page .case-scenario-grid {
|
||
display: grid !important;
|
||
grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
|
||
gap: 32px !important;
|
||
}
|
||
|
||
.solution-grid {
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
gap: 48px;
|
||
}
|
||
|
||
.contract-case-page .case-highlight-grid {
|
||
display: grid !important;
|
||
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
|
||
gap: 32px !important;
|
||
}
|
||
|
||
.contract-case-page .case-feature-card,
|
||
.solution-item,
|
||
.contract-case-page .case-highlight-card {
|
||
background: #fff;
|
||
border-radius: 18px;
|
||
box-shadow: 0 10px 22px rgba(15, 23, 42, 0.08);
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.contract-case-page .case-feature-card:hover,
|
||
.solution-item:hover,
|
||
.contract-case-page .case-highlight-card:hover {
|
||
transform: translateY(-4px);
|
||
box-shadow: 0 18px 36px rgba(15, 23, 42, 0.12);
|
||
}
|
||
|
||
.contract-case-page .case-feature-card {
|
||
display: block !important;
|
||
overflow: hidden !important;
|
||
}
|
||
|
||
.case-feature-card__visual {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 190px;
|
||
}
|
||
|
||
.case-feature-card__visual svg {
|
||
width: 84px;
|
||
height: 84px;
|
||
}
|
||
|
||
.case-feature-card__visual--illustration {
|
||
position: relative;
|
||
height: 192px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.case-feature-card__visual--illustration > svg {
|
||
position: absolute;
|
||
inset: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.magnifier,
|
||
.compare-arrow {
|
||
transition: transform 0.3s ease;
|
||
transform-box: fill-box;
|
||
transform-origin: center;
|
||
}
|
||
|
||
.scenario-card:hover .magnifier {
|
||
transform: scale(1.1);
|
||
}
|
||
|
||
.scenario-card:hover .compare-arrow {
|
||
transform: translateX(8px);
|
||
}
|
||
|
||
.scenario-card:hover .risk-dots {
|
||
animation: case-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||
}
|
||
|
||
.scenario-card:hover .diff-tags {
|
||
animation: case-bounce 1s infinite;
|
||
}
|
||
|
||
.visual-blue {
|
||
color: #2563eb;
|
||
background: linear-gradient(135deg, #eff6ff, #e0e7ff);
|
||
}
|
||
|
||
.visual-purple {
|
||
color: #7c3aed;
|
||
background: linear-gradient(135deg, #faf5ff, #fce7f3);
|
||
}
|
||
|
||
.visual-green {
|
||
color: #0d9488;
|
||
background: linear-gradient(135deg, #f0fdf4, #ccfbf1);
|
||
}
|
||
|
||
@keyframes case-pulse {
|
||
50% {
|
||
opacity: 0.5;
|
||
}
|
||
}
|
||
|
||
@keyframes case-bounce {
|
||
0%,
|
||
100% {
|
||
transform: translateY(-25%);
|
||
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
|
||
}
|
||
|
||
50% {
|
||
transform: translateY(0);
|
||
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||
}
|
||
}
|
||
|
||
.case-feature-card__head {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
padding: 32px 32px 0;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.case-feature-card h3,
|
||
.solution-item h4,
|
||
.case-highlight-card h3 {
|
||
margin: 0;
|
||
color: #111827;
|
||
font-size: 20px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.case-feature-card p,
|
||
.solution-item p,
|
||
.case-highlight-card p {
|
||
margin: 0;
|
||
color: #4b5563;
|
||
line-height: 1.7;
|
||
}
|
||
|
||
.case-feature-card > p {
|
||
padding: 0 32px 32px;
|
||
}
|
||
|
||
.case-icon-gradient,
|
||
.solution-icon,
|
||
.column-title span,
|
||
.highlight-num {
|
||
display: inline-flex;
|
||
flex-shrink: 0;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #fff;
|
||
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
|
||
border-radius: 12px;
|
||
}
|
||
|
||
.case-icon-gradient {
|
||
width: 40px;
|
||
height: 40px;
|
||
}
|
||
|
||
.case-icon-gradient svg {
|
||
width: 20px;
|
||
height: 20px;
|
||
}
|
||
|
||
.column-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16px;
|
||
margin-bottom: 32px;
|
||
}
|
||
|
||
.column-title span {
|
||
width: 48px;
|
||
height: 48px;
|
||
box-shadow: 0 10px 18px rgba(37, 99, 235, 0.18);
|
||
}
|
||
|
||
.column-title--danger span {
|
||
background: linear-gradient(135deg, #ef4444, #f97316);
|
||
}
|
||
|
||
.column-title h3 {
|
||
margin: 0;
|
||
color: #111827;
|
||
font-size: 26px;
|
||
font-weight: 800;
|
||
}
|
||
|
||
.column-title svg,
|
||
.solution-icon svg {
|
||
width: 24px;
|
||
height: 24px;
|
||
}
|
||
|
||
.solution-column {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 24px;
|
||
}
|
||
|
||
.solution-item {
|
||
display: flex;
|
||
gap: 20px;
|
||
padding: 24px;
|
||
border-left: 4px solid #60a5fa;
|
||
}
|
||
|
||
.solution-item--danger {
|
||
border-left-color: #f87171;
|
||
}
|
||
|
||
.solution-item--danger .solution-icon {
|
||
background: linear-gradient(135deg, #fee2e2, #ffedd5);
|
||
color: #dc2626;
|
||
}
|
||
|
||
.solution-icon {
|
||
width: 56px;
|
||
height: 56px;
|
||
}
|
||
|
||
.solution-item h4 {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.contract-case-page .case-highlight-card {
|
||
display: flex !important;
|
||
gap: 18px;
|
||
padding: 32px;
|
||
}
|
||
|
||
.highlight-num {
|
||
width: 48px;
|
||
height: 48px;
|
||
font-size: 22px;
|
||
font-weight: 800;
|
||
}
|
||
|
||
.case-highlight-card h3 {
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.case-cta {
|
||
padding: 80px 0;
|
||
color: #fff;
|
||
background: linear-gradient(90deg, #334155, #1e293b);
|
||
}
|
||
|
||
.case-cta__inner {
|
||
max-width: 896px;
|
||
text-align: center;
|
||
}
|
||
|
||
.case-cta h2 {
|
||
margin: 0 0 24px;
|
||
font-size: 40px;
|
||
font-weight: 800;
|
||
}
|
||
|
||
.case-cta p {
|
||
margin: 0 0 32px;
|
||
color: rgba(255, 255, 255, 0.9);
|
||
font-size: 20px;
|
||
}
|
||
|
||
.case-cta button {
|
||
padding: 16px 32px;
|
||
color: #2563eb;
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
background: #fff;
|
||
border: 0;
|
||
border-radius: 8px;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.case-cta button:hover {
|
||
background: #eff6ff;
|
||
}
|
||
|
||
@media (max-width: 1024px) {
|
||
.case-scenario-grid,
|
||
.solution-grid,
|
||
.case-highlight-grid {
|
||
grid-template-columns: 1fr !important;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.case-hero {
|
||
padding: 72px 0 56px;
|
||
}
|
||
|
||
.case-hero h1 {
|
||
font-size: 36px;
|
||
}
|
||
|
||
.case-hero p,
|
||
.section-heading p,
|
||
.case-cta p {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.case-tabs {
|
||
overflow-x: auto;
|
||
}
|
||
|
||
.case-tabs .case-container {
|
||
gap: 12px;
|
||
min-width: max-content;
|
||
}
|
||
|
||
.section-heading h2,
|
||
.case-cta h2 {
|
||
font-size: 30px;
|
||
}
|
||
|
||
.case-feature-card__head,
|
||
.case-feature-card > p,
|
||
.solution-item,
|
||
.case-highlight-card {
|
||
padding: 24px;
|
||
}
|
||
}
|
||
</style>
|