公司官网
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

297 lines
8.4 KiB

5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
2 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
2 months ago
5 months ago
  1. <script setup>
  2. import { ref, onMounted, computed, watch } from 'vue';
  3. import { useRoute, useRouter } from 'vue-router';
  4. import PageHeader from '../../components/PageHeader.vue';
  5. import { useCasesStore } from '@/stores/cases';
  6. const route = useRoute();
  7. const router = useRouter();
  8. const { selectedCase } = useCasesStore();
  9. // 获取案例ID
  10. const caseId = computed(() => Number(route.params.id));
  11. // 当前案例数据
  12. const currentCase = ref(null);
  13. // 默认的静态案例数据
  14. const defaultCaseData = {
  15. id: '1923006946802786306',
  16. title: '智慧校园管理系统',
  17. description: '为某知名高校开发的一体化校园管理系统,涵盖教学、行政、学生服务等多个模块',
  18. imageUrl: 'https://images.unsplash.com/photo-1523240795612-9a054b0db644?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80',
  19. categoryName: '企业系统',
  20. categoryId: 1,
  21. pdfUrl: '/docs/smart-campus-system.pdf',
  22. designUrl: 'https://www.figma.com/file/smart-campus-design',
  23. qrcodeUrl: '/images/smart-campus-qrcode.png',
  24. gallery: [
  25. {
  26. imageUrl: 'https://images.unsplash.com/photo-1523050854058-8df90110c9f1?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80',
  27. imageTitle: '系统主界面'
  28. },
  29. {
  30. imageUrl: 'https://images.unsplash.com/photo-1562774053-701939374585?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80',
  31. imageTitle: '移动端应用界面'
  32. },
  33. {
  34. imageUrl: 'https://images.unsplash.com/photo-1577896851231-70ef18881754?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80',
  35. imageTitle: '数据分析仪表盘'
  36. }
  37. ]
  38. };
  39. // 获取案例详情
  40. const getCaseDetail = async () => {
  41. console.log('当前案例ID:', caseId.value);
  42. console.log('所有案例:', selectedCase.value);
  43. // 尝试从selectedCase中获取数据
  44. if (selectedCase.value && selectedCase.value.length > 0) {
  45. const currentCaseData = selectedCase.value[0];
  46. console.log('使用的案例数据:', currentCaseData);
  47. // 处理图片路径,如果是数组则取第一个
  48. if (currentCaseData.imageUrl && typeof currentCaseData.imageUrl === 'string') {
  49. currentCaseData.image = currentCaseData.imageUrl.split(',')[0];
  50. }
  51. currentCase.value = currentCaseData;
  52. } else {
  53. // 如果没有可用数据,使用默认的静态数据
  54. console.log('使用默认的静态数据');
  55. currentCase.value = defaultCaseData;
  56. }
  57. };
  58. // 返回案例列表
  59. const goBackToList = () => {
  60. router.push('/cases');
  61. };
  62. // 监听路由参数变化
  63. watch(() => route.params.id, () => {
  64. getCaseDetail();
  65. });
  66. // 页面加载时获取数据
  67. onMounted(() => {
  68. getCaseDetail();
  69. });
  70. </script>
  71. <template>
  72. <div v-if="currentCase" class="case-detail-page">
  73. <!-- 页面头部 -->
  74. <PageHeader
  75. :title="currentCase.title"
  76. :subtitle="currentCase.description"
  77. :backgroundImage="currentCase.image || (currentCase.imageUrl && currentCase.imageUrl.split(',')[0])"
  78. height="50vh">
  79. <template #header-cta>
  80. <div class="header-cta" data-aos="fade-up" data-aos-delay="200">
  81. <button @click="goBackToList" class="btn-outline">
  82. <i class="fas fa-arrow-left"></i> 返回案例列表
  83. </button>
  84. </div>
  85. </template>
  86. </PageHeader>
  87. <!-- 案例资源链接 -->
  88. <section class="case-resources">
  89. <div class="container">
  90. <div class="resources-grid">
  91. <!-- PDF文档 -->
  92. <div class="resource-item" v-if="currentCase.pdfUrl" data-aos="fade-up">
  93. <div class="resource-icon">
  94. <i class="fas fa-file-pdf"></i>
  95. </div>
  96. <h3>功能说明文档</h3>
  97. <p>查看完整的项目功能说明文档</p>
  98. <a :href="currentCase.pdfUrl" target="_blank" class="btn-primary">
  99. 查看文档
  100. </a>
  101. </div>
  102. <!-- 设计稿链接 -->
  103. <div class="resource-item" v-if="currentCase.designUrl" data-aos="fade-up" data-aos-delay="100">
  104. <div class="resource-icon">
  105. <i class="fas fa-paint-brush"></i>
  106. </div>
  107. <h3>设计稿</h3>
  108. <p>浏览完整的项目设计方案</p>
  109. <a :href="currentCase.designUrl" target="_blank" class="btn-primary">
  110. 查看设计
  111. </a>
  112. </div>
  113. <!-- 小程序二维码 -->
  114. <div class="resource-item" v-if="currentCase.qrcodeUrl" data-aos="fade-up" data-aos-delay="200">
  115. <div class="resource-icon">
  116. <i class="fas fa-qrcode"></i>
  117. </div>
  118. <h3>小程序体验</h3>
  119. <p>扫码立即体验项目</p>
  120. <img :src="currentCase.qrcodeUrl" alt="小程序二维码" class="qrcode-image">
  121. </div>
  122. </div>
  123. </div>
  124. </section>
  125. <!-- 项目展示图片 -->
  126. <section class="case-gallery" v-if="currentCase.gallery && currentCase.gallery.length > 0">
  127. <div class="container">
  128. <h3>设计展示</h3>
  129. <div class="gallery-grid">
  130. <div v-for="(image, index) in currentCase.gallery"
  131. :key="index"
  132. class="gallery-item"
  133. data-aos="fade-up"
  134. :data-aos-delay="index * 100">
  135. <img :src="image.imageUrl" :alt="image.imageTitle">
  136. <div class="image-caption">{{ image.imageTitle }}</div>
  137. </div>
  138. </div>
  139. </div>
  140. </section>
  141. </div>
  142. </template>
  143. <style scoped>
  144. .case-detail-page {
  145. background-color: #f8f9fa;
  146. }
  147. .case-resources {
  148. padding: 60px 0;
  149. background-color: white;
  150. }
  151. .resources-grid {
  152. display: grid;
  153. grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  154. gap: 30px;
  155. max-width: 1200px;
  156. margin: 0 auto;
  157. }
  158. .resource-item {
  159. text-align: center;
  160. padding: 30px;
  161. background: white;
  162. border-radius: 12px;
  163. box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  164. transition: transform 0.3s ease;
  165. }
  166. .resource-item:hover {
  167. transform: translateY(-5px);
  168. }
  169. .resource-icon {
  170. font-size: 2.5rem;
  171. color: #007bff;
  172. margin-bottom: 20px;
  173. }
  174. .resource-item h3 {
  175. margin-bottom: 10px;
  176. color: #333;
  177. }
  178. .resource-item p {
  179. color: #666;
  180. margin-bottom: 20px;
  181. }
  182. .btn-primary {
  183. display: inline-block;
  184. padding: 10px 20px;
  185. background-color: #007bff;
  186. color: white;
  187. border-radius: 6px;
  188. text-decoration: none;
  189. transition: background-color 0.3s ease;
  190. }
  191. .btn-primary:hover {
  192. background-color: #0056b3;
  193. }
  194. .qrcode-image {
  195. max-width: 200px;
  196. margin: 0 auto;
  197. border-radius: 8px;
  198. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  199. }
  200. .case-gallery {
  201. padding: 60px 0;
  202. background-color: #f8f9fa;
  203. }
  204. .gallery-grid {
  205. display: grid;
  206. grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  207. gap: 30px;
  208. margin-top: 30px;
  209. }
  210. .gallery-item {
  211. position: relative;
  212. border-radius: 12px;
  213. overflow: hidden;
  214. box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  215. }
  216. .gallery-item img {
  217. width: 100%;
  218. height: 250px;
  219. object-fit: cover;
  220. transition: transform 0.3s ease;
  221. }
  222. .gallery-item:hover img {
  223. transform: scale(1.05);
  224. }
  225. .image-caption {
  226. position: absolute;
  227. bottom: 0;
  228. left: 0;
  229. right: 0;
  230. padding: 15px;
  231. background: rgba(0, 0, 0, 0.7);
  232. color: white;
  233. font-size: 0.9rem;
  234. }
  235. .container {
  236. max-width: 1200px;
  237. margin: 0 auto;
  238. padding: 0 20px;
  239. }
  240. h3 {
  241. text-align: center;
  242. margin-bottom: 30px;
  243. color: #333;
  244. }
  245. @media (max-width: 768px) {
  246. .resources-grid {
  247. grid-template-columns: 1fr;
  248. }
  249. .gallery-grid {
  250. grid-template-columns: 1fr;
  251. }
  252. .case-resources {
  253. padding: 40px 0;
  254. }
  255. .case-gallery {
  256. padding: 40px 0;
  257. }
  258. }
  259. </style>