Browse Source

feat: 优化案例详情页并添加备案功能

- 重构案例详情页数据结构,简化图片展示逻辑
- 添加备案徽记图标和点击跳转备案网站功能
- 调整页面样式和交互效果,提升用户体验
- 增加图片点击放大功能
master
主管理员 3 weeks ago
parent
commit
6084bf6f83
4 changed files with 95 additions and 37 deletions
  1. +36
    -1
      src/App.vue
  2. BIN
      src/assets/img/hui.png
  3. +1
    -1
      src/components/PageHeader.vue
  4. +58
    -35
      src/views/pages/CaseDetail.vue

+ 36
- 1
src/App.vue View File

@ -28,6 +28,11 @@ function toggleMobileNav() {
isMobileNavOpen.value = !isMobileNavOpen.value;
}
//
function openBeianSite() {
window.open('https://beian.miit.gov.cn', '_blank');
}
//
function closeMobileNav() {
isMobileNavOpen.value = false;
@ -130,7 +135,8 @@ onMounted(() => {
<a href="#">网站地图</a>
</div>
<div class="footer-record-number">
<span>{{ configParams.footer_record_number }}</span>
<img src="@/assets/img/hui.png" alt="备案徽记" class="beian-icon">
<span @click="openBeianSite" class="beian-link">{{ configParams.footer_record_number }}</span>
</div>
</div>
</div>
@ -311,6 +317,28 @@ main {
color: #fff;
}
.beian-link {
cursor: pointer;
transition: color 0.3s ease;
}
.beian-link:hover {
color: #0056b3;
text-decoration: underline;
}
.footer-record-number {
display: flex;
align-items: center;
gap: 8px;
}
.beian-icon {
width: 16px;
height: 16px;
object-fit: contain;
}
/* 移动菜单按钮 */
.mobile-menu-btn {
display: none;
@ -389,6 +417,7 @@ main {
color: #888;
word-break: break-all;
text-align: center;
justify-content: center;
}
}
@ -416,6 +445,12 @@ main {
.footer-record-number {
font-size: 11px;
padding: 0 5px;
justify-content: center;
}
.beian-icon {
width: 14px;
height: 14px;
}
}
</style>

BIN
src/assets/img/hui.png View File

Before After
Width: 20  |  Height: 22  |  Size: 16 KiB

+ 1
- 1
src/components/PageHeader.vue View File

@ -64,7 +64,7 @@ onMounted(() => {
<!-- 标题内容 -->
<div class="header-content">
<h1 data-aos="fade-up">{{ title }}</h1>
<p v-if="subtitle" data-aos="fade-up" data-aos-delay="200">{{ subtitle }}</p>
<p v-if="subtitle" data-aos="fade-up" data-aos-delay="200" style="max-width: 800px;padding: 0 20px;">{{ subtitle }}</p>
<!-- 插槽用于扩展按钮 -->
<slot name="header-cta"></slot>
</div>


+ 58
- 35
src/views/pages/CaseDetail.vue View File

@ -23,23 +23,13 @@ const defaultCaseData = {
imageUrl: 'https://images.unsplash.com/photo-1523240795612-9a054b0db644?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80',
categoryName: '企业系统',
categoryId: 1,
pdfUrl: '/docs/smart-campus-system.pdf',
designUrl: 'https://www.figma.com/file/smart-campus-design',
qrcodeUrl: '/images/smart-campus-qrcode.png',
gallery: [
{
imageUrl: 'https://images.unsplash.com/photo-1523050854058-8df90110c9f1?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80',
imageTitle: '系统主界面'
},
{
imageUrl: 'https://images.unsplash.com/photo-1562774053-701939374585?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80',
imageTitle: '移动端应用界面'
},
{
imageUrl: 'https://images.unsplash.com/photo-1577896851231-70ef18881754?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80',
imageTitle: '数据分析仪表盘'
}
]
clientUrl: '/docs/smart-campus-system.pdf',
challengeUrl: 'https://www.figma.com/file/smart-campus-design',
solutionUrl: '/images/smart-campus-qrcode.png',
results: 'https://demo.smart-campus.com',
testimonialUrl: 'https://images.unsplash.com/photo-1523050854058-8df90110c9f1?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80,https://images.unsplash.com/photo-1562774053-701939374585?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80,https://images.unsplash.com/photo-1577896851231-70ef18881754?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80',
content: '<h2>项目详情</h2><p>这是一个完整的智慧校园管理系统...</p>',
completionDate: '2024-12-01'
};
//
@ -76,6 +66,11 @@ const goBackToList = () => {
router.push('/cases');
};
//
const openImageInNewWindow = (imageUrl) => {
window.open(imageUrl.trim(), '_blank');
};
//
watch(() => route.params.id, () => {
getCaseDetail();
@ -93,8 +88,8 @@ onMounted(() => {
<PageHeader
:title="currentCase.title"
:subtitle="currentCase.description"
:backgroundImage="currentCase.image || (currentCase.imageUrl && currentCase.imageUrl.split(',')[0])"
height="50vh">
:backgroundImage="(currentCase.imageUrl && currentCase.imageUrl.split(',')[0])"
height="60vh">
<template #header-cta>
<div class="header-cta" data-aos="fade-up" data-aos-delay="200">
<button @click="goBackToList" class="btn-outline">
@ -109,54 +104,69 @@ onMounted(() => {
<div class="container">
<div class="resources-grid">
<!-- PDF文档 -->
<div class="resource-item" v-if="currentCase.pdfUrl" data-aos="fade-up">
<div class="resource-item" v-if="currentCase.clientUrl" data-aos="fade-up">
<div class="resource-icon">
<i class="fas fa-file-pdf"></i>
</div>
<h3>功能说明文档</h3>
<p>查看完整的项目功能说明文档</p>
<a :href="currentCase.pdfUrl" target="_blank" class="btn-primary">
<a :href="currentCase.clientUrl" target="_blank" class="btn-primary">
查看文档
</a>
</div>
<!-- 设计稿链接 -->
<div class="resource-item" v-if="currentCase.designUrl" data-aos="fade-up" data-aos-delay="100">
<div class="resource-item" v-if="currentCase.challengeUrl" data-aos="fade-up" data-aos-delay="100">
<div class="resource-icon">
<i class="fas fa-paint-brush"></i>
</div>
<h3>设计稿</h3>
<p>浏览完整的项目设计方案</p>
<a :href="currentCase.designUrl" target="_blank" class="btn-primary">
<a :href="currentCase.challengeUrl" target="_blank" class="btn-primary">
查看设计
</a>
</div>
<!-- 小程序二维码 -->
<div class="resource-item" v-if="currentCase.qrcodeUrl" data-aos="fade-up" data-aos-delay="200">
<div class="resource-item" v-if="currentCase.solutionUrl" data-aos="fade-up" data-aos-delay="200">
<div class="resource-icon">
<i class="fas fa-qrcode"></i>
</div>
<h3>小程序体验</h3>
<p>扫码立即体验项目</p>
<img :src="currentCase.qrcodeUrl" alt="小程序二维码" class="qrcode-image">
<img :src="currentCase.solutionUrl" alt="小程序二维码" class="qrcode-image">
</div>
<!-- 网站链接 -->
<div class="resource-item" v-if="currentCase.results" data-aos="fade-up" data-aos-delay="300">
<div class="resource-icon">
<i class="fas fa-globe"></i>
</div>
<h3>在线体验</h3>
<p>访问项目在线演示网站</p>
<a :href="currentCase.results" target="_blank" class="btn-primary">
访问网站
</a>
</div>
</div>
</div>
</section>
<!-- 项目展示图片 -->
<section class="case-gallery" v-if="currentCase.gallery && currentCase.gallery.length > 0">
<section class="case-gallery" v-if="currentCase.testimonialUrl">
<div class="container">
<h3>设计展示</h3>
<div class="gallery-grid">
<div v-for="(image, index) in currentCase.gallery"
<div v-for="(imageUrl, index) in currentCase.testimonialUrl.split(',')"
:key="index"
class="gallery-item"
data-aos="fade-up"
:data-aos-delay="index * 100">
<img :src="image.imageUrl" :alt="image.imageTitle">
<div class="image-caption">{{ image.imageTitle }}</div>
<img :src="imageUrl.trim()"
:alt="`设计展示 ${index + 1}`"
@click="openImageInNewWindow(imageUrl)"
class="clickable-image">
<!-- <div class="image-caption">设计展示 {{ index + 1 }}</div> -->
</div>
</div>
</div>
@ -233,13 +243,16 @@ onMounted(() => {
.btn-outline {
display: inline-block;
padding: 10px 20px;
background: transparent;
padding: 12px 24px;
background: rgba(255, 255, 255, 0.95);
color: #007bff;
border: 2px solid #007bff;
border-radius: 6px;
border-radius: 8px;
text-decoration: none;
font-weight: 500;
font-weight: 600;
font-size: 0.95rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
backdrop-filter: blur(10px);
transition: all 0.3s ease;
}
@ -247,6 +260,7 @@ onMounted(() => {
background: #007bff;
color: white;
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0, 123, 255, 0.3);
}
.qrcode-image {
@ -277,11 +291,20 @@ onMounted(() => {
.gallery-item img {
width: 100%;
height: 250px;
object-fit: cover;
height: auto;
object-fit: contain;
transition: transform 0.3s ease;
}
.clickable-image {
cursor: pointer;
}
.clickable-image:hover {
opacity: 0.9;
transform: scale(1.02);
}
.gallery-item:hover img {
transform: scale(1.05);
}


Loading…
Cancel
Save