| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833 |
- <template>
- <DefaultLayout>
- <!-- banner -->
- <section class="banner-section">
- <div class="banner-image animate-fade-in">
- <img src="@assets/products-banner.png" alt="" srcset="">
- </div>
- </section>
- <!-- skills section -->
- <section class="skills-section" ref="skillsSection">
- <!-- 白色背景的标题和菜单部分 -->
- <div class="skills-header">
- <div class="container">
- <h2 class="section-title animate-fade-up" :class="{ 'animate-visible': isSkillsVisible }">为企业打造了一个全面的数字化基础设施
- </h2>
- <div class="platform-tabs animate-fade-up" :class="{ 'animate-visible': isSkillsVisible }"
- style="animation-delay: 0.2s">
- <div v-for="(platform, index) in platforms" :key="index" class="tab-item animate-scale-in"
- :class="{ active: activePlatform === index, 'animate-visible': isSkillsVisible }"
- :style="{ 'animation-delay': `${0.1 * index}s` }" @click="switchPlatform(index)">
- {{ platform.name }}
- <img v-if="activePlatform === index" src="@assets/products-select.png" alt="" class="select-indicator">
- </div>
- </div>
- </div>
- </div>
- <!-- 内容部分 -->
- <div class="skills-content">
- <div class="container">
- <div class="content-wrapper animate-fade-up" :class="{ 'animate-visible': isSkillsVisible }"
- style="animation-delay: 0.4s" v-if="platforms[activePlatform]">
- <h3 class="content-title">{{ platforms[activePlatform].title }}</h3>
- <img src="@assets/products-select.png" alt="" class="title-indicator">
- <p class="content-subtitle">{{ platforms[activePlatform].subtitle }}</p>
- <!-- 图片轮播 -->
- <div class="carousel-container animate-scale-in" :class="{ 'animate-visible': isSkillsVisible }"
- style="animation-delay: 0.6s" v-if="platforms[activePlatform] && platforms[activePlatform].images">
- <div class="carousel-wrapper" @mouseenter="pauseAutoPlay" @mouseleave="resumeAutoPlay">
- <div class="carousel-track" :style="{ transform: `translateX(-${currentSlide * 100}%)` }">
- <div v-for="(image, index) in platforms[activePlatform].images" :key="index" class="carousel-slide">
- <img :src="image" :alt="`轮播图 ${index + 1}`">
- </div>
- </div>
- </div>
- <!-- 指示器 -->
- <div class="carousel-indicators">
- <div v-for="(_, index) in platforms[activePlatform].images" :key="index" class="indicator"
- :class="{ active: currentSlide === index }" @click="goToSlide(index)"></div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </section>
- <!-- 产品优势 section -->
- <section class="advantages-section" ref="advantagesSection">
- <div class="container">
- <h2 class="section-title animate-fade-up" :class="{ 'animate-visible': isAdvantagesVisible }">产品优势</h2>
- <img src="@assets/products-select.png" alt="" class="title-indicator animate-scale-in"
- :class="{ 'animate-visible': isAdvantagesVisible }" style="animation-delay: 0.2s">
- <div class="advantages-grid animate-fade-up" :class="{ 'animate-visible': isAdvantagesVisible }"
- style="animation-delay: 0.3s">
- <div v-for="(advantage, index) in advantages" :key="index" class="advantage-item animate-slide-up"
- :class="{ 'animate-visible': isAdvantagesVisible }" :style="{ 'animation-delay': `${0.1 * (index % 3)}s` }">
- <div class="advantage-content">
- <h3 class="advantage-title">{{ advantage.title }}</h3>
- <p class="advantage-description">{{ advantage.description }}</p>
- </div>
- <div class="advantage-image">
- <img :src="advantage.image" :alt="advantage.title">
- </div>
- </div>
- </div>
- </div>
- </section>
- </DefaultLayout>
- </template>
- <script>
- import { ref, onMounted, onUnmounted, nextTick } from 'vue'
- import DefaultLayout from '@/layouts/DefaultLayout.vue'
- import { getProjectClassifyList, getProjectList } from '@/api/modules/home'
- import productsBg01 from '@/assets/products-bg01.png'
- import productsBg02 from '@/assets/products-bg02.png'
- import productsYoushi01 from '@/assets/products-youshi-01.png'
- import productsYoushi02 from '@/assets/products-youshi-02.png'
- import productsYoushi03 from '@/assets/products-youshi-03.png'
- import productsYoushi04 from '@/assets/products-youshi-04.png'
- import productsYoushi05 from '@/assets/products-youshi-05.png'
- import productsYoushi06 from '@/assets/products-youshi-06.png'
- export default {
- name: 'ProductsPage',
- components: {
- DefaultLayout
- },
- setup() {
- // 环境变量
- const imgHost = import.meta.env.VITE_APP_IMG_HOST || ''
- // 响应式数据
- const activePlatform = ref(0)
- const currentSlide = ref(0)
- let autoPlayTimer = null
- // 动画状态管理
- const isSkillsVisible = ref(false)
- const isAdvantagesVisible = ref(false)
- // 元素引用
- const skillsSection = ref(null)
- const advantagesSection = ref(null)
- // 平台数据 - 从API获取
- const platforms = ref([])
- // 产品列表数据
- const productList = ref([])
- // 产品优势数据
- const advantages = ref([
- {
- title: '成本节约',
- description: '通过优化碳排放和碳资产配置,企业 可以在碳交易市场上卖出多余的碳排 放配额,实现成本节约。此外,提高 能效和采用清洁能源也有助于降低能 源成本。',
- image: productsYoushi01
- },
- {
- title: '市场竞争力提升',
- description: '积极管理碳资产的企业能够改善其 在绿色市场中的形象,吸引越来越 多注重可持续性的消费者和投资者, 从而提升市场竞争力。',
- image: productsYoushi02
- },
- {
- title: '详细合规与风险管理',
- description: '碳资产管理帮助企业准确监测和 报告碳排放,确保企业遵守相关 的环境法规和标准,降低因违反 碳排放规定而产生的法律和财务 风险。',
- image: productsYoushi03
- },
- {
- title: '技术创新与生产力提升',
- description: '碳资产管理促使企业投资于低碳技术和 能源效率改进,这些投资不仅有助于减 少碳排放,还能提高整体生产力和操作 效率。',
- image: productsYoushi04
- },
- {
- title: '长远战略规划',
- description: '碳资产管理有助于企业制定长期的碳 减排目标和策略,帮助企业在应对气 候变化的全球趋势中占据有利位置。 推动企业的可持续发展。',
- image: productsYoushi05
- },
- {
- title: '数据驱动决策支持',
- description: '碳资产管理平台提供的数据分析和报告功能, 能够帮助企业管理层做出更加明智的决策优 化资源分配,提高决策的数据驱动性。助力 企业制定长期的碳减排目标和策略。',
- image: productsYoushi06
- }
- ])
- // 切换平台
- const switchPlatform = async (index) => {
- activePlatform.value = index
- currentSlide.value = 0 // 切换平台时重置轮播
- resetAutoPlay()
- // 获取选中分类的产品列表
- if (platforms.value[index] && platforms.value[index].id) {
- await getProductsByClassify(platforms.value[index].id)
- }
- }
- // 切换轮播图
- const goToSlide = (index) => {
- currentSlide.value = index
- resetAutoPlay()
- }
- // 自动播放
- const startAutoPlay = () => {
- autoPlayTimer = setInterval(() => {
- if (platforms.value[activePlatform.value] && platforms.value[activePlatform.value].images) {
- const maxSlides = platforms.value[activePlatform.value].images.length
- currentSlide.value = (currentSlide.value + 1) % maxSlides
- }
- }, 4000)
- }
- // 重置自动播放
- const resetAutoPlay = () => {
- if (autoPlayTimer) {
- clearInterval(autoPlayTimer)
- }
- startAutoPlay()
- }
- // 暂停自动播放
- const pauseAutoPlay = () => {
- if (autoPlayTimer) {
- clearInterval(autoPlayTimer)
- }
- }
- // 恢复自动播放
- const resumeAutoPlay = () => {
- startAutoPlay()
- }
- // 获取产品分类列表
- const handleGetProjectClassifyList1 = async () => {
- try {
- const data = await getProjectClassifyList({ classifyType: 1 })
- console.log('产品中心分类列表:', data)
- if (data && data.rows && data.rows.length > 0) {
- // 处理分类数据,添加默认的展示信息
- platforms.value = data.rows.map(item => ({
- ...item,
- name: item.classifyName || item.name,
- title: item.classifyName || item.name,
- subtitle: item.classifyDesc || '为您提供专业的解决方案',
- images: [productsBg01, productsBg02, productsBg01] // 默认图片,后续可从API获取
- }))
- console.log('platforms.value', platforms.value)
- // 默认选中第一条,获取对应的产品列表
- if (platforms.value[0] && platforms.value[0].id) {
- await getProductsByClassify(platforms.value[0].id)
- }
- }
- } catch (error) {
- console.error('加载产品中心分类列表失败:', error)
- }
- }
- // 根据分类ID获取产品列表
- const getProductsByClassify = async (classifyId) => {
- try {
- const data = await getProjectList({
- classifyId: classifyId,
- projectType: 1 // 1:产品中心 2:行业案例
- })
- console.log('产品列表:', data)
- if (data && data.rows) {
- productList.value = data.rows
- // 更新当前选中平台的信息
- if (platforms.value[activePlatform.value] && data.rows.length > 0) {
- // 更新subtitle为第一条数据的projectProfile
- if (data.rows[0].projectProfile) {
- platforms.value[activePlatform.value].subtitle = data.rows[0].projectProfile
- }
- // 使用API返回的产品数据中的projectImage字段
- const images = data.rows
- .filter(item => item.projectImage) // 过滤掉没有图片的项目
- .map(item => imgHost + item.projectImage)
- .slice(0, 5) // 最多取5张图片
- if (images.length > 0) {
- platforms.value[activePlatform.value].images = images
- // 重置轮播到第一张
- currentSlide.value = 0
- } else {
- // 如果没有图片,使用默认图片
- platforms.value[activePlatform.value].images = [productsBg01, productsBg02, productsBg01]
- }
- }
- }
- } catch (error) {
- console.error('加载产品列表失败:', error)
- }
- }
- // 设置滚动动画观察器
- const setupScrollAnimations = () => {
- const observerOptions = {
- threshold: 0.2,
- rootMargin: '0px 0px -50px 0px'
- }
- const observer = new IntersectionObserver((entries) => {
- entries.forEach(entry => {
- if (entry.isIntersecting) {
- const target = entry.target
- if (target.classList.contains('skills-section')) {
- isSkillsVisible.value = true
- } else if (target.classList.contains('advantages-section')) {
- isAdvantagesVisible.value = true
- }
- }
- })
- }, observerOptions)
- // 观察各个区域
- nextTick(() => {
- if (skillsSection.value) observer.observe(skillsSection.value)
- if (advantagesSection.value) observer.observe(advantagesSection.value)
- })
- }
- onMounted(() => {
- handleGetProjectClassifyList1() // 获取产品分类列表
- startAutoPlay()
- // 设置滚动动画
- nextTick(() => {
- setupScrollAnimations()
- })
- // 延迟显示第一个区域
- setTimeout(() => {
- isSkillsVisible.value = true
- }, 500)
- })
- onUnmounted(() => {
- if (autoPlayTimer) {
- clearInterval(autoPlayTimer)
- }
- })
- return {
- activePlatform,
- currentSlide,
- platforms,
- productList,
- advantages,
- switchPlatform,
- goToSlide,
- pauseAutoPlay,
- resumeAutoPlay,
- imgHost,
- // 动画状态
- isSkillsVisible,
- isAdvantagesVisible,
- // 元素引用
- skillsSection,
- advantagesSection
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- // 动画定义
- @keyframes fadeIn {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
- }
- @keyframes fadeUp {
- from {
- opacity: 0;
- transform: translateY(40px);
- }
- to {
- opacity: 1;
- transform: translateY(0);
- }
- }
- @keyframes slideUp {
- from {
- opacity: 0;
- transform: translateY(30px);
- }
- to {
- opacity: 1;
- transform: translateY(0);
- }
- }
- @keyframes scaleIn {
- from {
- opacity: 0;
- transform: scale(0.8);
- }
- to {
- opacity: 1;
- transform: scale(1);
- }
- }
- // 动画类
- .animate-fade-in {
- animation: fadeIn 1s ease-out;
- }
- .animate-fade-up {
- opacity: 0;
- transform: translateY(40px);
- transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1);
- &.animate-visible {
- opacity: 1;
- transform: translateY(0);
- }
- }
- .animate-slide-up {
- opacity: 1;
- transform: translateY(20px);
- transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
- &.animate-visible {
- opacity: 1;
- transform: translateY(0);
- }
- }
- .animate-scale-in {
- opacity: 1;
- transform: scale(0.95);
- transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
- &.animate-visible {
- opacity: 1;
- transform: scale(1);
- }
- }
- // banner区域
- .banner-section {
- position: relative;
- .banner-image {
- img {
- width: 100%;
- }
- }
- }
- // skills区域
- .skills-section {
- .skills-header {
- background: #fff;
- padding: 60px 0 40px;
- .section-title {
- font-size: 36px;
- font-weight: 600;
- color: #333;
- text-align: center;
- margin-bottom: 50px;
- line-height: 1.4;
- }
- .platform-tabs {
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 60px;
- flex-wrap: wrap;
- .tab-item {
- position: relative;
- font-size: 18px;
- color: #666;
- cursor: pointer;
- padding: 10px 0;
- transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
- overflow: hidden;
- &::before {
- content: '';
- position: absolute;
- bottom: 0;
- left: 50%;
- width: 0;
- height: 2px;
- background: linear-gradient(90deg, #1890ff, #40a9ff);
- transform: translateX(-50%);
- transition: width 0.4s ease;
- }
- &:hover {
- color: #1890ff;
- transform: translateY(-2px);
- &::before {
- width: 100%;
- }
- }
- &.active {
- color: #1890ff;
- font-weight: 600;
- transform: translateY(-2px);
- &::before {
- width: 100%;
- }
- }
- .select-indicator {
- position: absolute;
- bottom: -35px;
- left: 50%;
- transform: translateX(-50%);
- width: 132px;
- height: auto;
- }
- }
- }
- }
- .skills-content {
- background: url('@assets/products-bg01.png') no-repeat center center;
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
- padding: 80px 0 100px;
- position: relative;
- // &::before {
- // content: '';
- // position: absolute;
- // top: 0;
- // left: 0;
- // right: 0;
- // bottom: 0;
- // background: rgba(0, 0, 0, 0.3);
- // z-index: 1;
- // }
- .container {
- position: relative;
- z-index: 2;
- }
- .content-wrapper {
- text-align: center;
- color: #333;
- .content-title {
- font-size: 32px;
- font-weight: 600;
- margin-bottom: 20px;
- position: relative;
- display: inline-block;
- }
- .title-indicator {
- width: 132px;
- height: auto;
- margin: 0 auto 20px;
- display: block;
- }
- .content-subtitle {
- font-size: 16px;
- line-height: 1.6;
- margin-bottom: 60px;
- max-width: 1200px;
- margin-left: auto;
- margin-right: auto;
- opacity: 0.9;
- }
- }
- }
- .carousel-container {
- max-width: 1434px;
- margin: 0 auto;
- .carousel-wrapper {
- position: relative;
- overflow: hidden;
- border-radius: 12px;
- box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
- .carousel-track {
- display: flex;
- transition: transform 0.5s ease-in-out;
- .carousel-slide {
- min-width: 100%;
- img {
- width: 100%;
- height: auto;
- max-height: 790px;
- display: block;
- }
- }
- }
- }
- .carousel-indicators {
- position: relative;
- display: flex;
- justify-content: center;
- gap: 12px;
- margin-top: -30px;
- .indicator {
- width: 8px;
- height: 8px;
- border-radius: 4px;
- background: rgba(0, 0, 0, 0.4);
- cursor: pointer;
- transition: all 0.3s ease;
- &:hover {
- background: rgba(255, 255, 255, 0.7);
- }
- &.active {
- width: 24px;
- background: #fff;
- animation: indicatorExpand 0.3s ease;
- }
- }
- }
- }
- }
- // 产品优势区域
- .advantages-section {
- background: #f8f9fa;
- padding: 80px 0;
- position: relative;
- &::before {
- position: absolute;
- content: '';
- left: 0;
- right: 0;
- top: 0;
- bottom: -138px;
- background: url('@assets/products-bg02.png') no-repeat center center;
- background-size: cover;
- }
- .container {
- position: relative;
- }
- .section-title {
- font-size: 36px;
- font-weight: 600;
- color: #333;
- text-align: center;
- margin-bottom: 20px;
- line-height: 1.4;
- }
- .title-indicator {
- width: 132px;
- height: auto;
- margin: 0 auto 60px;
- display: block;
- }
- .advantages-grid {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 49px;
- margin: 0 auto;
- .advantage-item {
- display: flex;
- align-items: center;
- background: linear-gradient(0deg, #DCEBFF 0%, #C8DFFF 100%);
- border-radius: 16px;
- padding: 30px;
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
- transition: all 0.3s ease;
- position: relative;
- overflow: hidden;
- &:hover {
- transform: translateY(-5px);
- box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
- }
- &::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(255, 255, 255, 0.1);
- opacity: 0;
- transition: opacity 0.3s ease;
- }
- &:hover::before {
- opacity: 1;
- }
- .advantage-content {
- flex: 1;
- color: #fff;
- margin-right: 30px;
- .advantage-title {
- font-size: 20px;
- font-weight: 600;
- margin-bottom: 16px;
- line-height: 1.3;
- color: #333;
- }
- .advantage-description {
- color: #666;
- font-size: 16px;
- line-height: 1.6;
- opacity: 0.95;
- }
- }
- .advantage-image {
- flex-shrink: 0;
- img {
- width: 208px;
- height: 161px;
- object-fit: contain;
- border-radius: 8px;
- }
- }
- }
- }
- }
- // 指示器动画
- @keyframes indicatorExpand {
- 0% {
- width: 8px;
- }
- 100% {
- width: 24px;
- }
- }
- // 响应式设计
- @media (max-width: 768px) {
- .skills-section {
- .skills-header {
- padding: 40px 0 30px;
- .section-title {
- font-size: 28px;
- margin-bottom: 30px;
- }
- .platform-tabs {
- gap: 30px;
- .tab-item {
- font-size: 16px;
- }
- }
- }
- .skills-content {
- padding: 60px 0 80px;
- .content-wrapper {
- .content-title {
- font-size: 24px;
- }
- .content-subtitle {
- font-size: 14px;
- margin-bottom: 40px;
- }
- }
- }
- .carousel-container {
- margin: 0 20px;
- }
- }
- .advantages-section {
- padding: 60px 0;
- .section-title {
- font-size: 28px;
- margin-bottom: 15px;
- }
- .title-indicator {
- width: 100px;
- margin-bottom: 40px;
- }
- .advantages-grid {
- grid-template-columns: 1fr;
- gap: 20px;
- padding: 0 20px;
- .advantage-item {
- flex-direction: column;
- text-align: center;
- padding: 30px 20px;
- .advantage-content {
- margin-right: 0;
- margin-bottom: 20px;
- .advantage-title {
- font-size: 20px;
- margin-bottom: 12px;
- }
- .advantage-description {
- font-size: 13px;
- }
- }
- .advantage-image {
- img {
- width: 160px;
- height: 124px;
- }
- }
- }
- }
- }
- }
- </style>
|