|
|
@@ -35,7 +35,7 @@ |
|
|
|
:parallax="true" |
|
|
|
class="h-[320px] sm:h-[320px] md:h-[768px] lg:h-[900px] swiper-container-1" |
|
|
|
> |
|
|
|
<SwiperSlide> |
|
|
|
<SwiperSlide> |
|
|
|
<div |
|
|
|
class="max-w-screen-2xl mx-auto h-full relative" |
|
|
|
:style="{ |
|
|
@@ -97,8 +97,8 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</SwiperSlide> |
|
|
|
<SwiperSlide v-if="!isMobile"> |
|
|
|
</SwiperSlide> |
|
|
|
<SwiperSlide v-if="!isMobile"> |
|
|
|
<div class="max-w-screen-2xl mx-auto h-full relative"> |
|
|
|
<video |
|
|
|
:src="homeA3Webp" |
|
|
@@ -217,7 +217,6 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</SwiperSlide> |
|
|
|
|
|
|
|
|
|
|
|
<div class="max-w-screen-2xl mx-auto relative"> |
|
|
|
<div |
|
|
@@ -227,158 +226,149 @@ |
|
|
|
</Swiper> |
|
|
|
</section> |
|
|
|
|
|
|
|
<!-- 按分类栏目展示 --> |
|
|
|
<!-- 按推荐产品展示 --> |
|
|
|
<section class="max-w-full mb-12 md:mb-32 xl:px-8 lg:px-6 md:px-4 px-4"> |
|
|
|
<div class="max-w-screen-2xl mx-auto relative"> |
|
|
|
<div |
|
|
|
class="justify-center text-cyan-400 text-base font-normal leading-tight mb-4" |
|
|
|
> |
|
|
|
{{ t("home.useCategoryTitle") }} |
|
|
|
{{ t("products.usage") }} |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="justify-center text-white font-normal mb-8 md:mb-16 text-xl sm:text-2xl md:text-4xl lg:text-6xl" |
|
|
|
> |
|
|
|
{{ t("home.useCategoryDescription") }} |
|
|
|
{{ t("products.usage_title") }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="max-w-screen-2xl mx-auto relative"> |
|
|
|
<!-- 企业产品 --> |
|
|
|
<div |
|
|
|
class="flex w-full relative mb-10 xl:mb-40 gap-10 flex-col xl:flex-row" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="select-none relative w-full xl:w-[65%] h-[280px] md:h-[320px] xl:h-[520px] animate-gradient-bg [background:linear-gradient(180deg,#444B55_0%,#98A3B4_95%)] from-zinc-900 to-zinc-800" |
|
|
|
<div class="max-w-screen-2xl mx-auto"> |
|
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-10 w-full"> |
|
|
|
<nuxt-link |
|
|
|
v-for="(recommend, index) in recommendList" |
|
|
|
:key="index" |
|
|
|
:to="`${homepagePath}products/${recommend.name}`" |
|
|
|
class="w-full h-full" |
|
|
|
> |
|
|
|
<img |
|
|
|
src="@/assets/images/business.webp" |
|
|
|
alt="business" |
|
|
|
class="max-h-full pl-0 md:pl-4 pt-0 md:pt-4 relative z-10" |
|
|
|
/> |
|
|
|
<span |
|
|
|
class="text-transparent bg-clip-text bg-gradient-to-r from-[rgba(255,255,255,0.05)] to-[rgba(255,255,255,0.08)] absolute hidden xl:block z-0 top-[35%] left-[62%] translate-y-[-50%] translate-x-[-50%] text-[170px] font-bold select-none" |
|
|
|
>Business</span |
|
|
|
> |
|
|
|
|
|
|
|
<div |
|
|
|
class="w-full absolute xl:hidden top-0 left-0 right-0 bottom-0 z-10 flex flex-col justify-center items-end p-4 md:p-8" |
|
|
|
class="w-full h-full bg-zinc-900 rounded-2xl p-4 flex flex-col items-center justify-start relative overflow-hidden group hover:bg-zinc-800 transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/10" |
|
|
|
> |
|
|
|
<!-- 图片容器 --> |
|
|
|
<div |
|
|
|
class="text-white text-4xl md:text-7xl font-bold mb-2 select-none" |
|
|
|
class="w-full aspect-square relative transition-all duration-300 overflow-hidden rounded-lg" |
|
|
|
> |
|
|
|
{{ t("home.business.title") }} |
|
|
|
</div> |
|
|
|
<div class="justify-center text-white text-xl font-normal mb-8"> |
|
|
|
{{ t("home.business.description") }} |
|
|
|
</div> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homepagePath}/products?audiences=1`" |
|
|
|
class="h-14 px-8 py-3.5 bg-white/10 hover:bg-white/15 rounded-[10px] outline outline-1 outline-white/20 backdrop-blur-md inline-flex flex-col justify-start items-start gap-3.5" |
|
|
|
> |
|
|
|
<div class="inline-flex justify-start items-center gap-2.5"> |
|
|
|
{{ t("home.business.view_details") }} |
|
|
|
<i class="icon-arrow-right text-xs ml-2"></i> |
|
|
|
<img |
|
|
|
:src="recommend?.image" |
|
|
|
class="w-full h-full object-cover transition-all duration-500 group-hover:scale-110" |
|
|
|
loading="lazy" |
|
|
|
alt="Product image" |
|
|
|
/> |
|
|
|
<div |
|
|
|
class="absolute inset-0 bg-gradient-to-t from-black/60 via-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" |
|
|
|
></div> |
|
|
|
<!-- 添加查看详情按钮 --> |
|
|
|
<div |
|
|
|
class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-4 group-hover:translate-y-0" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="px-4 py-2 bg-cyan-400/20 backdrop-blur-sm rounded-full text-white text-sm font-medium border border-cyan-400/30 transform transition-transform duration-300 group-hover:scale-105" |
|
|
|
> |
|
|
|
{{ t("products.view_details") }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="relative hidden xl:flex flex-1 flex-col gap-10"> |
|
|
|
<div class="w-full"> |
|
|
|
<div class="text-white text-6xl mb-4 mt-4 select-none"> |
|
|
|
{{ t("home.business.title") }} |
|
|
|
</div> |
|
|
|
<div class="justify-center text-white text-xl font-normal mb-8"> |
|
|
|
{{ t("home.business.description") }} |
|
|
|
</div> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homepagePath}/products?audiences=1`" |
|
|
|
class="h-14 px-8 py-3.5 bg-white/10 hover:bg-white/15 rounded-[10px] outline outline-1 outline-white/20 backdrop-blur-md inline-flex flex-col justify-start items-start gap-3.5" |
|
|
|
> |
|
|
|
<div class="inline-flex justify-start items-center gap-2.5"> |
|
|
|
{{ t("home.business.view_details") }} |
|
|
|
<i class="icon-arrow-right text-xs ml-2"></i> |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div |
|
|
|
class="bg-zinc-900/60 backdrop-blur-[120px] right-0 bottom-[-30%] static xl:absolute" |
|
|
|
> |
|
|
|
<div class="w-full h-full grid grid-cols-2"> |
|
|
|
<nuxt-link |
|
|
|
v-for="category in categoryList" |
|
|
|
:key="category.id" |
|
|
|
class="flex flex-col gap-4 items-center p-4 md:p-12 hover:bg-zinc-900/50 hover:scale-95 transition-all duration-300" |
|
|
|
v-show="category.audiences === 1" |
|
|
|
:to="`${category.link}`" |
|
|
|
<!-- 文字内容 --> |
|
|
|
<div |
|
|
|
class="w-full mt-4 min-h-[80px] transition-all duration-300 transform" |
|
|
|
> |
|
|
|
<img |
|
|
|
class="w-[200px] h-[200px] object-contain" |
|
|
|
:src="category.image" |
|
|
|
/> |
|
|
|
<div |
|
|
|
class="text-center flex justify-center text-white text-base font-bold" |
|
|
|
class="text-center text-white text-base font-bold leading-tight mb-2 line-clamp-2 group-hover:text-cyan-400 transition-colors duration-300" |
|
|
|
> |
|
|
|
{{ category.title }} |
|
|
|
{{ recommend.title }} |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="text-center text-white/50 text-sm max-w-[280px] line-clamp-2" |
|
|
|
class="text-center text-zinc-400 text-sm font-normal leading-tight line-clamp-2 group-hover:text-zinc-300 transition-colors duration-300" |
|
|
|
> |
|
|
|
{{ category.description }} |
|
|
|
{{ recommend.summary }} |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<!-- 个人产品 --> |
|
|
|
<!-- 按分类栏目展示 --> |
|
|
|
<section class="max-w-full mb-12 md:mb-32 xl:px-8 lg:px-6 md:px-4 px-4"> |
|
|
|
<div class="max-w-screen-2xl mx-auto relative"> |
|
|
|
<div |
|
|
|
class="flex w-full gap-8 relative mb-0 xl:mb-60 flex-col xl:flex-row" |
|
|
|
class="justify-center text-cyan-400 text-base font-normal leading-tight mb-4" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="flex-1 hidden xl:flex flex-col gap-10 relative top-[-80px]" |
|
|
|
> |
|
|
|
<div class="w-full"> |
|
|
|
<div |
|
|
|
class="justify-center text-white text-6xl whitespace-nowrap mb-4 mt-20 select-none" |
|
|
|
> |
|
|
|
{{ t("home.personal.title") }} |
|
|
|
</div> |
|
|
|
<div class="justify-center text-white text-xl font-normal mb-8"> |
|
|
|
{{ t("home.personal.description") }} |
|
|
|
</div> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homepagePath}/products?audiences=0`" |
|
|
|
class="h-14 px-8 py-3.5 bg-white/10 hover:bg-white/15 rounded-[10px] outline outline-1 outline-white/20 backdrop-blur-md inline-flex flex-col justify-start items-start gap-3.5" |
|
|
|
{{ t("home.useCategoryTitle") }} |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="justify-center text-white font-normal mb-8 md:mb-16 text-xl sm:text-2xl md:text-4xl lg:text-6xl" |
|
|
|
> |
|
|
|
{{ t("home.useCategoryDescription") }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="max-w-screen-2xl mx-auto relative"> |
|
|
|
<div class="w-full grid grid-cols-1 md:grid-cols-2 gap-8"> |
|
|
|
<!-- 企业产品 --> |
|
|
|
<div class="flex h-[240px] lg:h-[440px] xl:h-[540px] relative"> |
|
|
|
<div |
|
|
|
class="select-none relative w-full animate-gradient-bg [background:linear-gradient(180deg,#444B55_0%,#98A3B4_95%)] from-zinc-900 to-zinc-800" |
|
|
|
> |
|
|
|
<img |
|
|
|
src="@/assets/images/business.webp" |
|
|
|
alt="business" |
|
|
|
class="max-h-[90%] absolute bottom-0 left-0 z-10" |
|
|
|
/> |
|
|
|
<span |
|
|
|
class="text-transparent bg-clip-text bg-gradient-to-r from-[rgba(255,255,255,0.05)] to-[rgba(255,255,255,0.08)] absolute hidden xl:block z-0 top-[35%] left-[50%] translate-y-[-50%] translate-x-[-50%] text-[170px] font-bold select-none" |
|
|
|
>Business</span |
|
|
|
> |
|
|
|
<div class="inline-flex justify-start items-center gap-2.5"> |
|
|
|
{{ t("home.personal.view_details") }} |
|
|
|
<i class="icon-arrow-right text-xs ml-2"></i> |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="xl:flex flex-1 flex-col gap-10 absolute top-[10%] right-0" |
|
|
|
> |
|
|
|
<div class="w-full p-8"> |
|
|
|
<div class="text-white text-4xl mb-4 mt-4 select-none hidden lg:block"> |
|
|
|
{{ t("home.business.title") }} |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
<div class="justify-center text-white text-xl font-normal mb-8"> |
|
|
|
{{ t("home.business.description") }} |
|
|
|
</div> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homepagePath}/products?audiences=1`" |
|
|
|
class="h-14 px-8 py-3.5 whitespace-nowrap bg-white/10 hover:bg-white/15 rounded-[10px] outline outline-1 outline-white/20 backdrop-blur-md inline-flex flex-col justify-start items-start gap-3.5" |
|
|
|
> |
|
|
|
<div class="inline-flex justify-start items-center gap-2.5"> |
|
|
|
{{ t("home.business.view_details") }} |
|
|
|
<i class="icon-arrow-right text-xs ml-2"></i> |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div |
|
|
|
class="w-full xl:w-[75%] h-[280px] md:h-[320px] xl:h-[480px] select-none relative z-0 flex justify-end items-end animate-gradient-bg [background:linear-gradient(180deg,#0086f4_0%,#88d5fa_80%)]" |
|
|
|
> |
|
|
|
<img |
|
|
|
src="@/assets/images/personal.webp" |
|
|
|
alt="personal" |
|
|
|
class="pt-0 md:pt-20 max-h-full relative z-10" |
|
|
|
/> |
|
|
|
<span |
|
|
|
class="absolute text-transparent bg-clip-text bg-gradient-to-r from-[rgba(255,255,255,0.08)] to-[rgba(255,255,255,0.05)] hidden xl:block z-0 top-[25%] left-[35%] translate-y-[-50%] translate-x-[-50%] text-[160px] font-bold select-none" |
|
|
|
>Personal</span |
|
|
|
<div class="flex h-[240px] lg:h-[440px] xl:h-[540px] relative"> |
|
|
|
<div |
|
|
|
class="select-none overflow-hidden relative w-full animate-gradient-bg [background:linear-gradient(180deg,#0086f4_0%,#88d5fa_80%)] from-zinc-900 to-zinc-800" |
|
|
|
> |
|
|
|
|
|
|
|
<img |
|
|
|
src="@/assets/images/personal.webp" |
|
|
|
alt="personal" |
|
|
|
class="max-h-[90%] absolute bottom-0 right-[-80px] z-10" |
|
|
|
/> |
|
|
|
<span |
|
|
|
class="text-transparent bg-clip-text bg-gradient-to-r from-[rgba(255,255,255,0.05)] to-[rgba(255,255,255,0.08)] absolute hidden xl:block z-0 top-[35%] left-[50%] translate-y-[-50%] translate-x-[-50%] text-[170px] font-bold select-none" |
|
|
|
>Personal</span |
|
|
|
> |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="flex xl:hidden flex-col gap-10 absolute top-0 left-0 right-0 bottom-0 z-10 justify-center p-4 md:p-8" |
|
|
|
class="xl:flex flex-1 flex-col gap-10 absolute top-[10%] left-0" |
|
|
|
> |
|
|
|
<div class="w-full"> |
|
|
|
<div |
|
|
|
class="justify-center text-white text-4xl md:text-7xl font-bold mb-2 select-none" |
|
|
|
> |
|
|
|
<div class="w-full p-8"> |
|
|
|
<div class="text-white text-4xl mb-4 mt-4 select-none hidden lg:block"> |
|
|
|
{{ t("home.personal.title") }} |
|
|
|
</div> |
|
|
|
<div class="justify-center text-white text-xl font-normal mb-8"> |
|
|
@@ -386,7 +376,7 @@ |
|
|
|
</div> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homepagePath}/products?audiences=0`" |
|
|
|
class="h-14 px-8 py-3.5 bg-white/10 hover:bg-white/15 rounded-[10px] outline outline-1 outline-white/20 backdrop-blur-md inline-flex flex-col justify-start items-start gap-3.5" |
|
|
|
class="h-14 px-8 py-3.5 whitespace-nowrap bg-white/10 hover:bg-white/15 rounded-[10px] outline outline-1 outline-white/20 backdrop-blur-md inline-flex flex-col justify-start items-start gap-3.5" |
|
|
|
> |
|
|
|
<div class="inline-flex justify-start items-center gap-2.5"> |
|
|
|
{{ t("home.personal.view_details") }} |
|
|
@@ -397,202 +387,77 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 个人产品 --> |
|
|
|
<div |
|
|
|
class="bg-zinc-900/60 backdrop-blur-[120px] static left-0 bottom-[-32%] xl:absolute z-2" |
|
|
|
v-if="false" |
|
|
|
class="flex w-full gap-8 relative mb-0 xl:mb-60 flex-col xl:flex-row" |
|
|
|
> |
|
|
|
<div class="w-full h-full grid grid-cols-2 lg:grid-cols-3"> |
|
|
|
<nuxt-link |
|
|
|
v-for="category in categoryList" |
|
|
|
:key="category.id" |
|
|
|
class="flex flex-col gap-4 items-center py-4 px-4 md:py-12 md:px-6 hover:bg-zinc-900/50 hover:scale-95 transition-all duration-300" |
|
|
|
v-show="category.audiences === 0" |
|
|
|
:to="`${category.link}`" |
|
|
|
> |
|
|
|
<img |
|
|
|
class="w-[200px] h-[200px] object-contain" |
|
|
|
:src="category.image" |
|
|
|
/> |
|
|
|
<div |
|
|
|
class="flex-1 hidden xl:flex flex-col gap-10 relative top-[-80px]" |
|
|
|
> |
|
|
|
<div class="w-full"> |
|
|
|
<div |
|
|
|
class="text-center flex justify-center text-white text-base font-bold" |
|
|
|
class="justify-center text-white text-6xl whitespace-nowrap mb-4 mt-20 select-none" |
|
|
|
> |
|
|
|
{{ category.title }} |
|
|
|
{{ t("home.personal.title") }} |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="text-center text-white/50 text-sm max-w-[280px] line-clamp-2" |
|
|
|
> |
|
|
|
{{ category.description }} |
|
|
|
<div class="justify-center text-white text-xl font-normal mb-8"> |
|
|
|
{{ t("home.personal.description") }} |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homepagePath}/products?audiences=0`" |
|
|
|
class="h-14 px-8 py-3.5 bg-white/10 hover:bg-white/15 rounded-[10px] outline outline-1 outline-white/20 backdrop-blur-md inline-flex flex-col justify-start items-start gap-3.5" |
|
|
|
> |
|
|
|
<div class="inline-flex justify-start items-center gap-2.5"> |
|
|
|
{{ t("home.personal.view_details") }} |
|
|
|
<i class="icon-arrow-right text-xs ml-2"></i> |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<!-- 按用途产品展示 --> |
|
|
|
<section |
|
|
|
v-if="false" |
|
|
|
class="max-w-full mb-12 md:mb-32 xl:px-8 lg:px-6 md:px-4 px-4" |
|
|
|
> |
|
|
|
<div class="max-w-screen-2xl mx-auto relative"> |
|
|
|
<div |
|
|
|
class="justify-center text-cyan-400 text-base font-normal leading-tight mb-4" |
|
|
|
> |
|
|
|
{{ t("products.usage") }} |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="justify-center text-white font-normal mb-8 md:mb-16 text-xl sm:text-2xl md:text-4xl lg:text-6xl" |
|
|
|
> |
|
|
|
{{ t("products.usage_title") }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="max-w-screen-2xl mx-auto"> |
|
|
|
<div class="w-full mb-8"> |
|
|
|
<div class="flex flex-wrap items-center gap-2"> |
|
|
|
<div |
|
|
|
v-for="(usage, index) in typedUsageList" |
|
|
|
:key="usage.id" |
|
|
|
class="cursor-pointer select-none px-4 sm:px-7 py-2 sm:py-3 rounded-full border border-zinc-700 text-white transition-all duration-300 relative group" |
|
|
|
:class="{ |
|
|
|
'bg-cyan-400 border-zinc-900 pointer-events-none text-zinc-900': |
|
|
|
activeIndex === index, |
|
|
|
'hover:border-zinc-600': activeIndex !== index, |
|
|
|
}" |
|
|
|
@click="handleUsageClick(usage.id)" |
|
|
|
class="w-full select-none relative z-0 flex justify-end items-end animate-gradient-bg [background:linear-gradient(180deg,#0086f4_0%,#88d5fa_80%)]" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="usage-name text-center text-xs sm:text-sm font-normal leading-tight md:text-base transition-colors duration-300 relative z-10" |
|
|
|
> |
|
|
|
{{ usage.name }} |
|
|
|
<!-- 用途名称 --> |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="absolute inset-0 rounded-full bg-cyan-400/20 scale-0 transition-transform duration-300 group-hover:scale-100" |
|
|
|
></div> |
|
|
|
</div> |
|
|
|
<div class="flex items-center justify-center gap-4 ml-auto"> |
|
|
|
<div |
|
|
|
class="swiper-button-prev-2 bg-zinc-700 w-8 h-8 sm:w-10 sm:h-10 rounded-full flex items-center justify-center cursor-pointer hover:bg-zinc-600 transition-colors duration-200" |
|
|
|
<img |
|
|
|
src="@/assets/images/personal.webp" |
|
|
|
alt="personal" |
|
|
|
class="pt-0 md:pt-20 max-h-full relative z-10" |
|
|
|
/> |
|
|
|
<span |
|
|
|
class="absolute text-transparent bg-clip-text bg-gradient-to-r from-[rgba(255,255,255,0.08)] to-[rgba(255,255,255,0.05)] hidden xl:block z-0 top-[25%] left-[35%] translate-y-[-50%] translate-x-[-50%] text-[160px] font-bold select-none" |
|
|
|
>Personal</span |
|
|
|
> |
|
|
|
<i |
|
|
|
class="icon-arrow-left text-zinc-300 text-xs sm:text-sm font-normal" |
|
|
|
></i> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div |
|
|
|
class="swiper-button-next-2 bg-zinc-700 w-8 h-8 sm:w-10 sm:h-10 rounded-full flex items-center justify-center cursor-pointer hover:bg-zinc-600 transition-colors duration-200" |
|
|
|
class="flex xl:hidden flex-col gap-10 absolute top-0 left-0 right-0 bottom-0 z-10 justify-center p-4 md:p-8" |
|
|
|
> |
|
|
|
<i |
|
|
|
class="icon-arrow-right text-zinc-300 text-xs sm:text-sm font-normal" |
|
|
|
></i> |
|
|
|
<div class="w-full"> |
|
|
|
<div |
|
|
|
class="justify-center text-white text-4xl md:text-7xl font-bold mb-2 select-none" |
|
|
|
> |
|
|
|
{{ t("home.personal.title") }} |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="justify-center text-white text-xl font-normal mb-8" |
|
|
|
> |
|
|
|
{{ t("home.personal.description") }} |
|
|
|
</div> |
|
|
|
<nuxt-link |
|
|
|
:to="`${homepagePath}/products?audiences=0`" |
|
|
|
class="h-14 px-8 py-3.5 bg-white/10 hover:bg-white/15 rounded-[10px] outline outline-1 outline-white/20 backdrop-blur-md inline-flex flex-col justify-start items-start gap-3.5" |
|
|
|
> |
|
|
|
<div class="inline-flex justify-start items-center gap-2.5"> |
|
|
|
{{ t("home.personal.view_details") }} |
|
|
|
<i class="icon-arrow-right text-xs ml-2"></i> |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="max-w-screen-2xl mx-auto"> |
|
|
|
<div |
|
|
|
class="w-full h-[420px] sm:h-[300px] md:h-[350px] lg:h-[360px] xl:h-[380px] 2xl:h-[460px] relative" |
|
|
|
> |
|
|
|
<TransitionGroup name="slide-fade" tag="div" class="relative h-full"> |
|
|
|
<div :key="activeUsageId" class="w-full h-full"> |
|
|
|
<Swiper |
|
|
|
:modules="[Navigation]" |
|
|
|
:spaceBetween="30" |
|
|
|
:slidesPerView="4" |
|
|
|
:breakpoints="{ |
|
|
|
320: { slidesPerView: 1, spaceBetween: 10 }, |
|
|
|
448: { slidesPerView: 2, spaceBetween: 10 }, |
|
|
|
640: { slidesPerView: 3, spaceBetween: 20 }, |
|
|
|
1024: { slidesPerView: 4, spaceBetween: 20 }, |
|
|
|
1280: { slidesPerView: 4, spaceBetween: 30 }, |
|
|
|
1536: { slidesPerView: 4, spaceBetween: 30 }, |
|
|
|
}" |
|
|
|
:navigation="{ |
|
|
|
prevEl: '.swiper-button-prev-2', |
|
|
|
nextEl: '.swiper-button-next-2', |
|
|
|
}" |
|
|
|
class="h-full" |
|
|
|
> |
|
|
|
<SwiperSlide |
|
|
|
v-for="product in activeProducts" |
|
|
|
:key="product.id" |
|
|
|
class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4" |
|
|
|
> |
|
|
|
<div class="w-full h-full p-2"> |
|
|
|
<nuxt-link :to="product.link" class="block w-full h-full"> |
|
|
|
<div |
|
|
|
class="w-full h-full bg-zinc-900 rounded-2xl p-4 flex flex-col items-center justify-start relative overflow-hidden group hover:bg-zinc-800 transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/10" |
|
|
|
> |
|
|
|
<!-- 图片加载占位 --> |
|
|
|
<div |
|
|
|
v-if="!isImageLoaded[product.id]" |
|
|
|
class="absolute inset-0 bg-gradient-to-br from-zinc-800 via-zinc-700 to-zinc-800 animate-gradient" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="absolute inset-0 flex items-center justify-center" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="w-8 h-8 border-4 border-cyan-400/20 border-t-cyan-400 rounded-full animate-spin" |
|
|
|
></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<!-- 图片容器 --> |
|
|
|
<div |
|
|
|
class="w-full aspect-square relative transition-all duration-300 overflow-hidden rounded-lg" |
|
|
|
:class="{ 'opacity-0': !isImageLoaded[product.id] }" |
|
|
|
> |
|
|
|
<img |
|
|
|
:src="product.image" |
|
|
|
:alt="product.title" |
|
|
|
class="w-full h-full object-cover transition-all duration-500 group-hover:scale-110" |
|
|
|
@load="handleImageLoad(product.id)" |
|
|
|
@error="handleImageError(product.id)" |
|
|
|
loading="lazy" |
|
|
|
/> |
|
|
|
<div |
|
|
|
class="absolute inset-0 bg-gradient-to-t from-black/60 via-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" |
|
|
|
></div> |
|
|
|
<!-- 添加查看详情按钮 --> |
|
|
|
<div |
|
|
|
class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-4 group-hover:translate-y-0" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="px-4 py-2 bg-cyan-400/20 backdrop-blur-sm rounded-full text-white text-sm font-medium border border-cyan-400/30 transform transition-transform duration-300 group-hover:scale-105" |
|
|
|
> |
|
|
|
{{ t("products.view_details") }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<!-- 文字内容 --> |
|
|
|
<div |
|
|
|
class="w-full mt-4 min-h-[80px] transition-all duration-300 transform" |
|
|
|
:class="{ |
|
|
|
'opacity-0 translate-y-4': |
|
|
|
!isImageLoaded[product.id], |
|
|
|
'opacity-100 translate-y-0': |
|
|
|
isImageLoaded[product.id], |
|
|
|
}" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="text-center text-white text-base font-bold leading-tight mb-2 line-clamp-2 group-hover:text-cyan-400 transition-colors duration-300" |
|
|
|
> |
|
|
|
{{ product.title }} |
|
|
|
</div> |
|
|
|
<div |
|
|
|
class="text-center text-zinc-400 text-sm font-normal leading-tight line-clamp-2 group-hover:text-zinc-300 transition-colors duration-300" |
|
|
|
> |
|
|
|
{{ product.description }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</nuxt-link> |
|
|
|
</div> |
|
|
|
</SwiperSlide> |
|
|
|
</Swiper> |
|
|
|
</div> |
|
|
|
</TransitionGroup> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<!-- 核心展示 --> |
|
|
@@ -813,25 +678,9 @@ interface Product { |
|
|
|
link: string; |
|
|
|
description?: string; |
|
|
|
name?: string; |
|
|
|
} |
|
|
|
|
|
|
|
interface Usage { |
|
|
|
id: number; |
|
|
|
name: string; |
|
|
|
category?: string; |
|
|
|
products: Product[]; |
|
|
|
} |
|
|
|
|
|
|
|
interface Category { |
|
|
|
id: number; |
|
|
|
title: string; |
|
|
|
description: string; |
|
|
|
capacities: string[]; |
|
|
|
summary: string; |
|
|
|
sort: number; |
|
|
|
image: string; |
|
|
|
link: string; |
|
|
|
audiences: number; |
|
|
|
recommend: boolean; |
|
|
|
recommendIndex: number; |
|
|
|
summary?: string; |
|
|
|
} |
|
|
|
|
|
|
|
// 使用i18n |
|
|
@@ -850,231 +699,26 @@ const videoSrc = ref(video); |
|
|
|
/** |
|
|
|
* 使用计算属性获取当前语言的数据文件URL |
|
|
|
*/ |
|
|
|
const usageDataUrl = computed(() => { |
|
|
|
return `/data/usages-${locale.value}.json`; |
|
|
|
}); |
|
|
|
|
|
|
|
const categoryDataUrl = computed(() => { |
|
|
|
return `/data/categories-${locale.value}.json`; |
|
|
|
}); |
|
|
|
|
|
|
|
const productsDataUrl = computed(() => { |
|
|
|
return `/data/products-${locale.value}.json`; |
|
|
|
}); |
|
|
|
|
|
|
|
const homepagePath = computed(() => { |
|
|
|
return locale.value === "zh" ? "" : `/${locale.value}`; |
|
|
|
}); |
|
|
|
|
|
|
|
// 获取按用途产品数据 |
|
|
|
const usageList = ref<Usage[]>([]); |
|
|
|
const isLoadingUsage = ref(true); |
|
|
|
const activeUsageId = ref(1); |
|
|
|
|
|
|
|
// 获取按分类栏目数据 |
|
|
|
const categoryList = ref<Category[]>([]); |
|
|
|
const isLoadingCategory = ref(true); |
|
|
|
|
|
|
|
// 加载用途数据 |
|
|
|
const loadUsageData = async () => { |
|
|
|
try { |
|
|
|
isLoadingUsage.value = true; |
|
|
|
// 使用fetch获取数据 |
|
|
|
if (process.client) { |
|
|
|
const response = await fetch(usageDataUrl.value); |
|
|
|
if (!response.ok) { |
|
|
|
throw new Error(`加载用途数据失败: ${response.status}`); |
|
|
|
} |
|
|
|
const usageData = await response.json(); |
|
|
|
// 加载对应的产品数据 |
|
|
|
const productsResponse = await fetch(productsDataUrl.value); |
|
|
|
if (!productsResponse.ok) { |
|
|
|
throw new Error(`加载产品数据失败: ${productsResponse.status}`); |
|
|
|
} |
|
|
|
|
|
|
|
const productsData = await productsResponse.json(); |
|
|
|
// 处理数据 |
|
|
|
usageList.value = usageData |
|
|
|
.map((usage: any) => { |
|
|
|
// 为每种用途找到对应的产品 |
|
|
|
const usageProducts = []; |
|
|
|
|
|
|
|
// 按照正确的设计模式:使用用途的title与产品的usage数组进行匹配 |
|
|
|
// 找出所有usage属性包含当前用途title的产品 |
|
|
|
const matchedProducts = productsData.filter( |
|
|
|
(product: any) => |
|
|
|
product.usage && |
|
|
|
Array.isArray(product.usage) && |
|
|
|
product.usage.includes(usage.title) |
|
|
|
); |
|
|
|
|
|
|
|
// 将匹配的产品添加到列表 |
|
|
|
if (matchedProducts.length > 0) { |
|
|
|
matchedProducts.forEach((product: any) => { |
|
|
|
usageProducts.push({ |
|
|
|
id: product.id, |
|
|
|
title: product.title, |
|
|
|
image: product.image, |
|
|
|
link: `${homepagePath.value}/products/${product.name}`, |
|
|
|
description: product.summary, |
|
|
|
}); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
// 如果没有找到匹配的产品,添加一个占位产品 |
|
|
|
const recommendList = ref<Product[]>([]); |
|
|
|
|
|
|
|
usageProducts.push({ |
|
|
|
id: `placeholder-${usage.id}`, |
|
|
|
title: usage.title, |
|
|
|
image: ``, |
|
|
|
link: `${homepagePath.value}/products?usage=${encodeURIComponent( |
|
|
|
usage.title |
|
|
|
)}`, |
|
|
|
description: "", |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
id: parseInt(usage.id) || 0, |
|
|
|
name: usage.title, |
|
|
|
category: usage.category || "", |
|
|
|
products: usageProducts, |
|
|
|
}; |
|
|
|
}) |
|
|
|
.sort((a: any, b: any) => a.id - b.id); |
|
|
|
|
|
|
|
// 设置默认选中的用途 |
|
|
|
if (usageList.value.length > 0) { |
|
|
|
activeUsageId.value = usageList.value[0].id; |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error("Error loading usage data:", error); |
|
|
|
} finally { |
|
|
|
isLoadingUsage.value = false; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 加载分类数据 |
|
|
|
const loadCategoryData = async () => { |
|
|
|
try { |
|
|
|
isLoadingCategory.value = true; |
|
|
|
// 使用fetch获取数据 |
|
|
|
if (process.client) { |
|
|
|
const response = await fetch(categoryDataUrl.value); |
|
|
|
if (!response.ok) { |
|
|
|
throw new Error(`加载分类数据失败: ${response.status}`); |
|
|
|
} |
|
|
|
|
|
|
|
const data = await response.json(); |
|
|
|
|
|
|
|
// 处理数据 |
|
|
|
categoryList.value = data |
|
|
|
.map((category: any) => { |
|
|
|
return { |
|
|
|
id: parseInt(category.id) || 0, |
|
|
|
title: category.title || "", |
|
|
|
description: category.description || "", |
|
|
|
image: category.image || "", |
|
|
|
link: `${homepagePath.value}/products?category=${encodeURIComponent( |
|
|
|
category.title |
|
|
|
)}&audiences=${category.audiences}`, |
|
|
|
capacities: category.capacities || [], |
|
|
|
summary: category.summary || "", |
|
|
|
sort: category.sort || 0, |
|
|
|
audiences: category.audiences, |
|
|
|
}; |
|
|
|
}) |
|
|
|
.sort((a: any, b: any) => a.id - b.id); |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error("Error loading category data:", error); |
|
|
|
} finally { |
|
|
|
isLoadingCategory.value = false; |
|
|
|
} |
|
|
|
const loadRecommendData = async () => { |
|
|
|
const productsResponse = await fetch(productsDataUrl.value); |
|
|
|
const productsData = await productsResponse.json(); |
|
|
|
recommendList.value = productsData |
|
|
|
.filter((product: Product) => product.recommend) |
|
|
|
.sort((a: Product, b: Product) => b.recommendIndex - a.recommendIndex); |
|
|
|
}; |
|
|
|
|
|
|
|
// 当页面加载或语言改变时加载数据 |
|
|
|
onMounted(() => { |
|
|
|
loadUsageData(); |
|
|
|
loadCategoryData(); |
|
|
|
}); |
|
|
|
|
|
|
|
watch(locale, () => { |
|
|
|
loadUsageData(); |
|
|
|
loadCategoryData(); |
|
|
|
}); |
|
|
|
|
|
|
|
// 计算当前用途列表 |
|
|
|
const typedUsageList = computed(() => { |
|
|
|
return usageList.value as Usage[]; |
|
|
|
}); |
|
|
|
|
|
|
|
// 计算当前激活的索引 |
|
|
|
const activeIndex = computed(() => { |
|
|
|
return typedUsageList.value.findIndex( |
|
|
|
(item) => item.id === activeUsageId.value |
|
|
|
); |
|
|
|
}); |
|
|
|
|
|
|
|
const activeProducts = computed(() => { |
|
|
|
const currentUsage = typedUsageList.value.find( |
|
|
|
(item: Usage) => item.id === activeUsageId.value |
|
|
|
); |
|
|
|
return currentUsage?.products || []; |
|
|
|
}); |
|
|
|
|
|
|
|
// 图片加载状态 |
|
|
|
const isImageLoaded = ref<Record<number, boolean>>({}); |
|
|
|
const imageErrors = ref<Record<number, boolean>>({}); |
|
|
|
|
|
|
|
// 监听图片加载状态 |
|
|
|
watch( |
|
|
|
activeProducts, |
|
|
|
(newProducts: Product[]) => { |
|
|
|
if (process.client) { |
|
|
|
newProducts.forEach((product: Product) => { |
|
|
|
if (product.image) { |
|
|
|
const img = new window.Image(); |
|
|
|
img.onload = () => handleImageLoad(product.id); |
|
|
|
img.onerror = () => handleImageError(product.id); |
|
|
|
img.src = product.image; |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
}, |
|
|
|
{ immediate: true } |
|
|
|
); |
|
|
|
|
|
|
|
// 处理图片加载 |
|
|
|
const handleImageLoad = (id: number) => { |
|
|
|
if (process.client) { |
|
|
|
isImageLoaded.value[id] = true; |
|
|
|
imageErrors.value[id] = false; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 处理图片加载错误 |
|
|
|
const handleImageError = (id: number) => { |
|
|
|
if (process.client) { |
|
|
|
console.error(`Failed to load image for product ${id}`); |
|
|
|
isImageLoaded.value[id] = true; |
|
|
|
imageErrors.value[id] = true; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 处理用途点击 |
|
|
|
const handleUsageClick = (id: number) => { |
|
|
|
if (process.client) { |
|
|
|
// 重置图片加载状态 |
|
|
|
isImageLoaded.value = {}; |
|
|
|
imageErrors.value = {}; |
|
|
|
activeUsageId.value = id; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 计算当前分类列表 |
|
|
|
const typedCategoryList = computed(() => { |
|
|
|
return categoryList.value as Category[]; |
|
|
|
loadRecommendData(); |
|
|
|
}); |
|
|
|
|
|
|
|
// SEO优化 |