417 lines
18 KiB
Vue
417 lines
18 KiB
Vue
<script setup>
|
||
import { ref, onMounted } from 'vue'
|
||
import { useRoute } from 'vue-router'
|
||
import { Swiper, SwiperSlide } from 'swiper/vue'
|
||
import { Autoplay, Pagination, Navigation, EffectFade } from 'swiper/modules'
|
||
import AOS from 'aos'
|
||
import 'aos/dist/aos.css'
|
||
import 'swiper/css'
|
||
import 'swiper/css/pagination'
|
||
import 'swiper/css/navigation'
|
||
import 'swiper/css/effect-fade'
|
||
|
||
const route = useRoute()
|
||
const activeTab = ref('1')
|
||
const modules = [Autoplay, Pagination, Navigation, EffectFade]
|
||
|
||
onMounted(() => {
|
||
AOS.init({
|
||
duration: 1200,
|
||
offset: 120,
|
||
easing: 'ease-out-cubic',
|
||
once: false
|
||
})
|
||
})
|
||
|
||
const project = {
|
||
id: route.params.id,
|
||
title: '电商平台',
|
||
cover: 'https://pic.rmb.bdstatic.com/bjh/80852bfe7c321988191838517ba64e309354.jpeg@h_1280',
|
||
category: 'Web应用',
|
||
tags: ['Vue3', 'Node.js', 'TypeScript', 'MongoDB', 'Docker'],
|
||
author: '技术团队',
|
||
price: '¥ 29,999',
|
||
description: '基于微服务架构的电商平台,包含商品管理、订单系统、支付对接等模块。采用前后端分离设计,提供完整的API文档和部署方案。系统具有高度可扩展性和定制化能力,适合中小型企业快速搭建自有电商平台。',
|
||
features: [
|
||
'响应式设计,支持多端访问',
|
||
'完整的商品管理系统',
|
||
'订单处理和物流跟踪',
|
||
'多种支付方式集成',
|
||
'会员管理和积分系统',
|
||
'数据分析和报表功能'
|
||
],
|
||
technicalStack: ['前端:Vue3 + TypeScript', '后端:PHP【Laravel 12.x】 + MySQL', '部署:Docker + Kubernetes'],
|
||
screenshots: [
|
||
'https://pic.rmb.bdstatic.com/bjh/80852bfe7c321988191838517ba64e309354.jpeg@h_1280',
|
||
'https://pic.rmb.bdstatic.com/bjh/80852bfe7c321988191838517ba64e309354.jpeg@h_1280',
|
||
'https://pic.rmb.bdstatic.com/bjh/80852bfe7c321988191838517ba64e309354.jpeg@h_1280'
|
||
],
|
||
video: 'http://d-jy.nailaoyun.cn//storage/video//20250327/2cc1abf9bd69410ce7c69660daf54260.mp4',
|
||
wechatQR: '/assets/qr-code.png'
|
||
}
|
||
|
||
const relatedProjects = [
|
||
{
|
||
id: 1,
|
||
title: 'CRM系统',
|
||
cover: 'https://pic.rmb.bdstatic.com/bjh/80852bfe7c321988191838517ba64e309354.jpeg@h_1280',
|
||
tags: ['Vue3', 'Express'],
|
||
price: '¥ 19,999'
|
||
},
|
||
{
|
||
id: 2,
|
||
title: '数据分析平台',
|
||
cover: 'https://pic.rmb.bdstatic.com/bjh/80852bfe7c321988191838517ba64e309354.jpeg@h_1280',
|
||
tags: ['React', 'Python'],
|
||
price: '¥ 24,999'
|
||
},
|
||
{
|
||
id: 3,
|
||
title: '企业官网',
|
||
cover: 'https://pic.rmb.bdstatic.com/bjh/80852bfe7c321988191838517ba64e309354.jpeg@h_1280',
|
||
tags: ['Nuxt.js', 'Tailwind'],
|
||
price: '¥ 9,999'
|
||
}
|
||
]
|
||
|
||
// 轮播图自动播放配置
|
||
const swiperOptions = {
|
||
delay: 5000,
|
||
disableOnInteraction: false
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div class="bg-gradient-to-b from-gray-50 to-white dark:from-gray-900 dark:to-gray-800 min-h-screen py-12">
|
||
<div class="max-w-6xl mx-auto px-6">
|
||
<!-- 项目封面 -->
|
||
<div class="mb-10" data-aos="fade-up">
|
||
<div class="relative h-[50vh] min-h-[400px] rounded-3xl overflow-hidden shadow-2xl">
|
||
<img
|
||
:src="project.cover"
|
||
class="w-full h-full object-cover"
|
||
alt="项目封面"
|
||
/>
|
||
<div class="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent"></div>
|
||
|
||
<div class="absolute bottom-0 left-0 right-0 p-8 md:p-12">
|
||
<div class="flex flex-wrap gap-2 mb-4">
|
||
<span
|
||
class="px-4 py-1.5 bg-white/10 backdrop-blur-md text-white text-sm font-medium rounded-full border border-white/20"
|
||
>
|
||
{{ project.category }}
|
||
</span>
|
||
</div>
|
||
|
||
<h1 class="text-3xl md:text-5xl font-bold text-white mb-4">{{ project.title }}</h1>
|
||
|
||
<div class="flex flex-wrap gap-2 mb-6">
|
||
<span
|
||
v-for="tag in project.tags"
|
||
:key="tag"
|
||
class="px-3 py-1 bg-rose-500/20 backdrop-blur-md text-rose-100 text-sm font-medium rounded-full border border-rose-500/30"
|
||
>
|
||
{{ tag }}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 项目信息卡片 -->
|
||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12" data-aos="fade-up">
|
||
<!-- 左侧信息 -->
|
||
<div class="lg:col-span-2">
|
||
<div class="bg-white dark:bg-gray-800 rounded-3xl shadow-xl p-8">
|
||
<!-- 标签页导航 -->
|
||
<div class="border-b border-gray-200 dark:border-gray-700 mb-8">
|
||
<nav class="flex space-x-8">
|
||
<button
|
||
@click="activeTab = '1'"
|
||
class="py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200"
|
||
:class="activeTab === '1' ? 'border-rose-500 text-rose-600 dark:text-rose-400' : 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'"
|
||
>
|
||
项目详情
|
||
</button>
|
||
<button
|
||
@click="activeTab = '2'"
|
||
class="py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200"
|
||
:class="activeTab === '2' ? 'border-rose-500 text-rose-600 dark:text-rose-400' : 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'"
|
||
>
|
||
项目截图
|
||
</button>
|
||
<button
|
||
@click="activeTab = '3'"
|
||
class="py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200"
|
||
:class="activeTab === '3' ? 'border-rose-500 text-rose-600 dark:text-rose-400' : 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'"
|
||
>
|
||
演示视频
|
||
</button>
|
||
</nav>
|
||
</div>
|
||
|
||
<!-- 标签页内容 -->
|
||
<div>
|
||
<!-- 项目详情 -->
|
||
<div v-if="activeTab === '1'" class="space-y-8">
|
||
<div>
|
||
<h3 class="text-xl font-bold mb-4 text-gray-900 dark:text-white flex items-center">
|
||
<span class="w-8 h-8 rounded-full bg-rose-100 dark:bg-rose-900/30 text-rose-600 dark:text-rose-400 flex items-center justify-center mr-3">
|
||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||
</svg>
|
||
</span>
|
||
项目描述
|
||
</h3>
|
||
<p class="text-gray-600 dark:text-gray-300 leading-relaxed">{{ project.description }}</p>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 class="text-xl font-bold mb-4 text-gray-900 dark:text-white flex items-center">
|
||
<span class="w-8 h-8 rounded-full bg-rose-100 dark:bg-rose-900/30 text-rose-600 dark:text-rose-400 flex items-center justify-center mr-3">
|
||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||
</svg>
|
||
</span>
|
||
核心功能
|
||
</h3>
|
||
<ul class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||
<li
|
||
v-for="(feature, index) in project.features"
|
||
:key="index"
|
||
class="flex items-start"
|
||
>
|
||
<div class="flex-shrink-0 w-5 h-5 rounded-full bg-rose-100 dark:bg-rose-900/30 flex items-center justify-center text-rose-600 dark:text-rose-400 mr-3 mt-0.5">
|
||
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||
</svg>
|
||
</div>
|
||
<span class="text-gray-700 dark:text-gray-300">{{ feature }}</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 class="text-xl font-bold mb-4 text-gray-900 dark:text-white flex items-center">
|
||
<span class="w-8 h-8 rounded-full bg-rose-100 dark:bg-rose-900/30 text-rose-600 dark:text-rose-400 flex items-center justify-center mr-3">
|
||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
|
||
</svg>
|
||
</span>
|
||
技术栈
|
||
</h3>
|
||
<ul class="space-y-2">
|
||
<li
|
||
v-for="(tech, index) in project.technicalStack"
|
||
:key="index"
|
||
class="flex items-center bg-gray-50 dark:bg-gray-700/50 rounded-lg p-3"
|
||
>
|
||
<div class="flex-shrink-0 w-5 h-5 rounded-full bg-rose-100 dark:bg-rose-900/30 flex items-center justify-center text-rose-600 dark:text-rose-400 mr-3">
|
||
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||
</svg>
|
||
</div>
|
||
<span class="text-gray-700 dark:text-gray-300">{{ tech }}</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 项目截图 -->
|
||
<div v-else-if="activeTab === '2'">
|
||
<swiper
|
||
:modules="modules"
|
||
:effect="'fade'"
|
||
:autoplay="swiperOptions"
|
||
:pagination="{
|
||
clickable: true,
|
||
dynamicBullets: true,
|
||
dynamicMainBullets: 3
|
||
}"
|
||
:navigation="true"
|
||
:loop="true"
|
||
class="rounded-2xl overflow-hidden shadow-lg"
|
||
>
|
||
<swiper-slide
|
||
v-for="(img, index) in project.screenshots"
|
||
:key="index"
|
||
>
|
||
<div class="relative h-[50vh] min-h-[400px] w-full">
|
||
<img
|
||
:src="img"
|
||
class="w-full h-full object-contain bg-gray-100 dark:bg-gray-900"
|
||
:alt="`项目截图 ${index + 1}`"
|
||
/>
|
||
</div>
|
||
</swiper-slide>
|
||
</swiper>
|
||
</div>
|
||
|
||
<!-- 演示视频 -->
|
||
<div v-else-if="activeTab === '3'">
|
||
<div class="aspect-w-16 aspect-h-9 rounded-2xl overflow-hidden shadow-lg">
|
||
<iframe
|
||
:src="project.video"
|
||
class="w-full h-[50vh] min-h-[400px]"
|
||
frameborder="0"
|
||
allowfullscreen
|
||
></iframe>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧信息 -->
|
||
<div>
|
||
<div class="bg-white dark:bg-gray-800 rounded-3xl shadow-xl p-8 sticky top-8">
|
||
<div class="mb-6">
|
||
<p class="text-sm text-gray-500 dark:text-gray-400 mb-1">价格</p>
|
||
<p class="text-3xl font-bold text-rose-600 dark:text-rose-400">{{ project.price }}</p>
|
||
</div>
|
||
|
||
<div class="mb-6">
|
||
<p class="text-sm text-gray-500 dark:text-gray-400 mb-1">开发团队</p>
|
||
<p class="text-gray-900 dark:text-white font-medium">{{ project.author }}</p>
|
||
</div>
|
||
|
||
<div class="space-y-4">
|
||
<button class="w-full py-3 bg-rose-600 hover:bg-rose-700 text-white rounded-xl shadow-lg hover:shadow-xl transition-all duration-300 flex items-center justify-center">
|
||
<span>立即咨询</span>
|
||
</button>
|
||
|
||
<button class="w-full py-3 bg-white dark:bg-gray-700 text-rose-600 dark:text-rose-400 border border-rose-200 dark:border-rose-800/30 rounded-xl shadow-md hover:shadow-lg transition-all duration-300 flex items-center justify-center">
|
||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
|
||
</svg>
|
||
<span>收藏项目</span>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
|
||
<p class="text-center text-gray-500 dark:text-gray-400 mb-4">扫码添加微信</p>
|
||
<div class="flex justify-center">
|
||
<!-- <img-->
|
||
<!-- :src="project.wechatQR"-->
|
||
<!-- class="w-32 h-32 object-cover rounded-lg border border-gray-200 dark:border-gray-700"-->
|
||
<!-- alt="微信二维码"-->
|
||
<!-- />-->
|
||
<img
|
||
src="@/assets/qr-code.png"
|
||
class="w-48 h-68 object-cover rounded-lg border border-gray-200 dark:border-gray-700"
|
||
alt="微信二维码"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 相关项目 -->
|
||
<section class="mb-12" data-aos="fade-up">
|
||
<h2 class="text-2xl md:text-3xl font-bold mb-8 text-gray-900 dark:text-white">
|
||
<span class="relative">
|
||
相关项目
|
||
<span class="absolute -bottom-2 left-0 w-1/4 h-1 bg-gradient-to-r from-rose-400 to-rose-600 rounded-full"></span>
|
||
</span>
|
||
</h2>
|
||
|
||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||
<div
|
||
v-for="related in relatedProjects"
|
||
:key="related.id"
|
||
class="group bg-white dark:bg-gray-800 rounded-3xl shadow-lg hover:shadow-xl transition-all duration-500 overflow-hidden transform hover:-translate-y-2"
|
||
>
|
||
<div class="relative h-48 overflow-hidden">
|
||
<img
|
||
:src="related.cover"
|
||
class="w-full h-full object-cover transform transition-transform duration-700 group-hover:scale-110"
|
||
:alt="related.title"
|
||
/>
|
||
<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-500"></div>
|
||
</div>
|
||
|
||
<div class="p-6">
|
||
<h3 class="text-lg font-bold mb-2 text-gray-900 dark:text-white group-hover:text-rose-600 dark:group-hover:text-rose-400 transition-colors">
|
||
{{ related.title }}
|
||
</h3>
|
||
|
||
<div class="flex flex-wrap gap-2 mb-4">
|
||
<span
|
||
v-for="tag in related.tags"
|
||
:key="tag"
|
||
class="px-3 py-1 bg-rose-50 dark:bg-rose-900/20 text-rose-600 dark:text-rose-300 text-xs font-medium rounded-lg"
|
||
>
|
||
{{ tag }}
|
||
</span>
|
||
</div>
|
||
|
||
<div class="flex justify-between items-center">
|
||
<p class="font-bold text-rose-600 dark:text-rose-400">{{ related.price }}</p>
|
||
<button class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300">
|
||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
/* 优化 Swiper 导航样式 */
|
||
:deep(.swiper-button-next),
|
||
:deep(.swiper-button-prev) {
|
||
width: 3rem;
|
||
height: 3rem;
|
||
background-color: rgba(255, 255, 255, 0.9);
|
||
backdrop-filter: blur(8px);
|
||
border-radius: 50%;
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
|
||
color: #111827;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
:deep(.swiper-button-next:hover),
|
||
:deep(.swiper-button-prev:hover) {
|
||
background-color: white;
|
||
color: #f43f5e;
|
||
transform: scale(1.05);
|
||
}
|
||
|
||
:deep(.swiper-button-next::after),
|
||
:deep(.swiper-button-prev::after) {
|
||
font-size: 1.25rem;
|
||
font-weight: bold;
|
||
}
|
||
|
||
:deep(.swiper-pagination-bullet) {
|
||
width: 10px;
|
||
height: 10px;
|
||
background-color: rgba(255, 255, 255, 0.5);
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
:deep(.swiper-pagination-bullet-active) {
|
||
background-color: #f43f5e;
|
||
width: 24px;
|
||
border-radius: 5px;
|
||
}
|
||
|
||
/* 添加轻奢风格的渐变背景和阴影效果 */
|
||
.bg-gradient-luxury {
|
||
background: linear-gradient(135deg, #f6f8fb 0%, #f0f4f8 100%);
|
||
}
|
||
|
||
/* 暗色模式下的轻奢风格 */
|
||
@media (prefers-color-scheme: dark) {
|
||
.bg-gradient-luxury {
|
||
background: linear-gradient(135deg, #1a1d23 0%, #111827 100%);
|
||
}
|
||
}
|
||
</style>
|