hookehuyr

feat(页面): 实现页面数据接口对接及功能优化

- 在Masters、NewsDetail、Students和Volunteers页面中对接API接口获取真实数据
- 优化页面跳转逻辑,支持通过参数传递id
- 清理未使用的Vant组件声明
- 更新.gitignore文件添加stdj忽略项
...@@ -40,4 +40,6 @@ coverage/ ...@@ -40,4 +40,6 @@ coverage/
40 .eslintcache 40 .eslintcache
41 41
42 # History 42 # History
43 -.history/
...\ No newline at end of file ...\ No newline at end of file
43 +.history/
44 +
45 +stdj
......
1 /* 1 /*
2 * @Date: 2023-08-24 09:42:27 2 * @Date: 2023-08-24 09:42:27
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-10-31 11:10:04 4 + * @LastEditTime: 2025-10-31 13:23:09
5 * @FilePath: /stdj_h5/src/api/index.js 5 * @FilePath: /stdj_h5/src/api/index.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
......
...@@ -11,40 +11,11 @@ declare module 'vue' { ...@@ -11,40 +11,11 @@ declare module 'vue' {
11 LoadingSpinner: typeof import('./components/LoadingSpinner.vue')['default'] 11 LoadingSpinner: typeof import('./components/LoadingSpinner.vue')['default']
12 RouterLink: typeof import('vue-router')['RouterLink'] 12 RouterLink: typeof import('vue-router')['RouterLink']
13 RouterView: typeof import('vue-router')['RouterView'] 13 RouterView: typeof import('vue-router')['RouterView']
14 - VanBadge: typeof import('vant/es')['Badge']
15 VanButton: typeof import('vant/es')['Button'] 14 VanButton: typeof import('vant/es')['Button']
16 - VanCard: typeof import('vant/es')['Card']
17 VanCell: typeof import('vant/es')['Cell'] 15 VanCell: typeof import('vant/es')['Cell']
18 - VanCellGroup: typeof import('vant/es')['CellGroup']
19 - VanCheckbox: typeof import('vant/es')['Checkbox']
20 - VanCollapse: typeof import('vant/es')['Collapse']
21 - VanCollapseItem: typeof import('vant/es')['CollapseItem']
22 - VanEmpty: typeof import('vant/es')['Empty']
23 - VanField: typeof import('vant/es')['Field']
24 - VanForm: typeof import('vant/es')['Form']
25 - VanGrid: typeof import('vant/es')['Grid']
26 - VanGridItem: typeof import('vant/es')['GridItem']
27 VanIcon: typeof import('vant/es')['Icon'] 16 VanIcon: typeof import('vant/es')['Icon']
28 - VanImage: typeof import('vant/es')['Image']
29 VanList: typeof import('vant/es')['List'] 17 VanList: typeof import('vant/es')['List']
30 - VanNavBar: typeof import('vant/es')['NavBar']
31 - VanNoticeBar: typeof import('vant/es')['NoticeBar']
32 VanOverlay: typeof import('vant/es')['Overlay'] 18 VanOverlay: typeof import('vant/es')['Overlay']
33 - VanProgress: typeof import('vant/es')['Progress']
34 - VanRate: typeof import('vant/es')['Rate']
35 - VanSidebar: typeof import('vant/es')['Sidebar']
36 - VanSidebarItem: typeof import('vant/es')['SidebarItem']
37 - VanStep: typeof import('vant/es')['Step']
38 - VanSteps: typeof import('vant/es')['Steps']
39 - VanSwipe: typeof import('vant/es')['Swipe']
40 - VanSwipeItem: typeof import('vant/es')['SwipeItem']
41 - VanSwitch: typeof import('vant/es')['Switch']
42 - VanTab: typeof import('vant/es')['Tab']
43 - VanTabbar: typeof import('vant/es')['Tabbar']
44 - VanTabbarItem: typeof import('vant/es')['TabbarItem']
45 - VanTabs: typeof import('vant/es')['Tabs']
46 - VanTag: typeof import('vant/es')['Tag']
47 VideoPlayer: typeof import('./components/VideoPlayer.vue')['default'] 19 VideoPlayer: typeof import('./components/VideoPlayer.vue')['default']
48 - WaterfallGallery: typeof import('./components/WaterfallGallery.vue')['default']
49 } 20 }
50 } 21 }
......
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
99 <div class="column-overlay"></div> 99 <div class="column-overlay"></div>
100 <div class="column-text"> 100 <div class="column-text">
101 <h3 class="column-title">{{ item.name }}</h3> 101 <h3 class="column-title">{{ item.name }}</h3>
102 - <div class="more-button" @click="viewMore(item.name)"> 102 + <div class="more-button" @click="viewMore(item.name, item.id)">
103 <span class="more-text">查看更多</span> 103 <span class="more-text">查看更多</span>
104 </div> 104 </div>
105 </div> 105 </div>
...@@ -284,22 +284,24 @@ watch(currentStep, () => { ...@@ -284,22 +284,24 @@ watch(currentStep, () => {
284 }, { deep: true }) 284 }, { deep: true })
285 285
286 // 查看更多按钮点击事件 286 // 查看更多按钮点击事件
287 -const viewMore = (type) => { 287 +const viewMore = (type, id) => {
288 switch (type) { 288 switch (type) {
289 case '法会流程': 289 case '法会流程':
290 console.log('法会流程', currentStep.value); 290 console.log('法会流程', currentStep.value);
291 + // TODO: 提供URL跳转页面
292 + location.href = 'http://www.baidu.com'
291 break 293 break
292 case '三师七证': 294 case '三师七证':
293 // 跳转到三师七证页面的逻辑 295 // 跳转到三师七证页面的逻辑
294 - router.push('/masters') 296 + router.push(`/masters?pid=${id}`)
295 break 297 break
296 case '戒子': 298 case '戒子':
297 // 跳转到戒子页面的逻辑 299 // 跳转到戒子页面的逻辑
298 - router.push('/students') 300 + router.push(`/students?cid=${id}`)
299 break 301 break
300 case '义工': 302 case '义工':
301 // 跳转到义工页面的逻辑 303 // 跳转到义工页面的逻辑
302 - router.push('/volunteers') 304 + router.push(`/volunteers?cid=${id}`)
303 break 305 break
304 } 306 }
305 } 307 }
...@@ -406,7 +408,7 @@ const attachTransitionEndOnce = (looping) => { ...@@ -406,7 +408,7 @@ const attachTransitionEndOnce = (looping) => {
406 const handleNewsClick = (item) => { 408 const handleNewsClick = (item) => {
407 console.log('点击新闻:', item) 409 console.log('点击新闻:', item)
408 // 这里可以添加跳转到新闻详情页面的逻辑 410 // 这里可以添加跳转到新闻详情页面的逻辑
409 - router.push({ name: 'NewsDetail', params: { id: item.date } }) 411 + router.push({ name: 'NewsDetail', params: { id: item.id } })
410 } 412 }
411 </script> 413 </script>
412 414
......
...@@ -39,10 +39,13 @@ ...@@ -39,10 +39,13 @@
39 </template> 39 </template>
40 40
41 <script setup> 41 <script setup>
42 -import { ref } from 'vue' 42 +import { ref, onMounted } from 'vue'
43 import { useRouter } from 'vue-router' 43 import { useRouter } from 'vue-router'
44 import { useTitle } from '@vueuse/core'; 44 import { useTitle } from '@vueuse/core';
45 45
46 +// 导入接口
47 +import { getSSQZAPI } from '@/api/index.js'
48 +
46 const router = useRouter() 49 const router = useRouter()
47 50
48 useTitle('三師七證') 51 useTitle('三師七證')
...@@ -112,6 +115,16 @@ const gridItems = ref([ ...@@ -112,6 +115,16 @@ const gridItems = ref([
112 const goDetail = (item) => { 115 const goDetail = (item) => {
113 router.push(`/masters/${item.id}`) 116 router.push(`/masters/${item.id}`)
114 } 117 }
118 +
119 +const pid = ref(router.currentRoute.value.query.pid)
120 +
121 +onMounted(async () => {
122 + // 调用接口获取三师七证数据
123 + const { code, list } = await getSSQZAPI({ pid: pid.value });
124 + if (code) {
125 + console.warn(list);
126 + }
127 +})
115 </script> 128 </script>
116 129
117 <style scoped> 130 <style scoped>
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
30 import { ref, onMounted } from 'vue' 30 import { ref, onMounted } from 'vue'
31 import { useRoute, useRouter } from 'vue-router' 31 import { useRoute, useRouter } from 'vue-router'
32 import { Toast } from 'vant' 32 import { Toast } from 'vant'
33 +import dayjs from 'dayjs'
34 +
35 +// 导入接口
36 +import { getArticleDetailAPI } from '@/api/index.js'
33 37
34 const route = useRoute() 38 const route = useRoute()
35 const router = useRouter() 39 const router = useRouter()
...@@ -60,21 +64,31 @@ const article = ref({ ...@@ -60,21 +64,31 @@ const article = ref({
60 }) 64 })
61 65
62 // 组件挂载时加载数据 66 // 组件挂载时加载数据
63 -onMounted(() => { 67 +onMounted(async () => {
64 const articleId = route.params.id 68 const articleId = route.params.id
65 - console.log('Loading article data for ID:', articleId) 69 + const { code, data } = await getArticleDetailAPI({ i: articleId })
66 - // 这里可以根据ID加载具体的文章数据 70 + if (code) {
71 + article.value = {
72 + ...data,
73 + id: data.id,
74 + title: data.post_title,
75 + content: data.post_content,
76 + publishDate: dayjs(data.post_date).format('YYYY-MM-DD HH:mm:ss'),
77 + author: data.post_author,
78 + coverImage: data.photo,
79 + }
80 + }
67 }) 81 })
68 </script> 82 </script>
69 83
70 <style scoped> 84 <style scoped>
71 .page-container { 85 .page-container {
72 - min-height: 100vh;
73 background: #f5f5f5; 86 background: #f5f5f5;
74 } 87 }
75 88
76 .content-container { 89 .content-container {
77 background-color: #F2EBDB; 90 background-color: #F2EBDB;
91 + min-height: 100vh;
78 } 92 }
79 93
80 .article-header { 94 .article-header {
......
1 <!-- 1 <!--
2 * @Date: 2025-10-30 20:52:19 2 * @Date: 2025-10-30 20:52:19
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-10-30 21:22:42 4 + * @LastEditTime: 2025-10-31 13:19:13
5 * @FilePath: /stdj_h5/src/views/Students.vue 5 * @FilePath: /stdj_h5/src/views/Students.vue
6 * @Description: 戒子页面 - 图片瀑布流展示 6 * @Description: 戒子页面 - 图片瀑布流展示
7 --> 7 -->
...@@ -71,15 +71,22 @@ ...@@ -71,15 +71,22 @@
71 71
72 <script setup> 72 <script setup>
73 import { ref, reactive, onMounted } from 'vue' 73 import { ref, reactive, onMounted } from 'vue'
74 -import { generateWaterfallData } from '@/utils/mockData'
75 import { useTitle } from '@vueuse/core'; 74 import { useTitle } from '@vueuse/core';
75 +import { useRouter } from 'vue-router'
76 +
77 +// 导入接口
78 +import { getImgStreamAPI } from '@/api/index.js'
76 79
77 useTitle('同戒录') 80 useTitle('同戒录')
78 81
82 +const router = useRouter()
83 +
84 +const cid = ref(router.currentRoute.value.query.cid)
85 +
79 // 响应式数据 86 // 响应式数据
80 const loading = ref(false) 87 const loading = ref(false)
81 const finished = ref(false) 88 const finished = ref(false)
82 -const currentPage = ref(1) 89 +const currentPage = ref(0) // API使用0作为起始页码
83 const pageSize = 10 90 const pageSize = 10
84 const allImages = ref([]) 91 const allImages = ref([])
85 const columns = reactive([[], []]) 92 const columns = reactive([[], []])
...@@ -92,21 +99,37 @@ const selectedImage = ref(null) ...@@ -92,21 +99,37 @@ const selectedImage = ref(null)
92 const onLoad = async () => { 99 const onLoad = async () => {
93 loading.value = true 100 loading.value = true
94 101
95 - // 模拟网络延迟
96 - await new Promise(resolve => setTimeout(resolve, 1000))
97 -
98 try { 102 try {
99 - const newData = generateWaterfallData(currentPage.value, pageSize) 103 + // 调用正式接口
100 - 104 + const response = await getImgStreamAPI({
101 - if (newData.length === 0) { 105 + cid: cid.value,
102 - finished.value = true 106 + page: currentPage.value,
107 + limit: pageSize
108 + })
109 +
110 + if (response.code && response.list) {
111 + const newData = response.list.map(item => ({
112 + id: item.id,
113 + url: item.photo,
114 + title: item.post_title,
115 + description: item.post_content,
116 + date: item.post_date,
117 + height: Math.floor(Math.random() * 200) + 200 // 随机高度用于瀑布流布局
118 + }))
119 +
120 + if (newData.length === 0) {
121 + finished.value = true
122 + } else {
123 + allImages.value.push(...newData)
124 + distributeImages(newData)
125 + currentPage.value++
126 + }
103 } else { 127 } else {
104 - allImages.value.push(...newData) 128 + finished.value = true
105 - distributeImages(newData)
106 - currentPage.value++
107 } 129 }
108 } catch (error) { 130 } catch (error) {
109 console.error('加载数据失败:', error) 131 console.error('加载数据失败:', error)
132 + finished.value = true
110 } finally { 133 } finally {
111 loading.value = false 134 loading.value = false
112 } 135 }
......
1 <!-- 1 <!--
2 * @Date: 2025-01-01 15:20:00 2 * @Date: 2025-01-01 15:20:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-10-30 21:15:28 4 + * @LastEditTime: 2025-10-31 13:20:49
5 * @FilePath: /stdj_h5/src/views/Volunteers.vue 5 * @FilePath: /stdj_h5/src/views/Volunteers.vue
6 * @Description: 义工页面 - 图片瀑布流展示 6 * @Description: 义工页面 - 图片瀑布流展示
7 --> 7 -->
...@@ -49,16 +49,16 @@ ...@@ -49,16 +49,16 @@
49 <div class="close-btn" @click="closeOverlay"> 49 <div class="close-btn" @click="closeOverlay">
50 <van-icon name="cross" size="1.5rem" color="#fff" /> 50 <van-icon name="cross" size="1.5rem" color="#fff" />
51 </div> 51 </div>
52 - 52 +
53 <!-- 图片展示 --> 53 <!-- 图片展示 -->
54 <div class="overlay-image-wrapper"> 54 <div class="overlay-image-wrapper">
55 - <img 55 + <img
56 - :src="selectedImage?.url" 56 + :src="selectedImage?.url"
57 :alt="selectedImage?.title" 57 :alt="selectedImage?.title"
58 class="overlay-image" 58 class="overlay-image"
59 /> 59 />
60 </div> 60 </div>
61 - 61 +
62 <!-- 描述内容 --> 62 <!-- 描述内容 -->
63 <div class="overlay-description"> 63 <div class="overlay-description">
64 <h3 class="overlay-title">{{ selectedImage?.title }}</h3> 64 <h3 class="overlay-title">{{ selectedImage?.title }}</h3>
...@@ -71,15 +71,22 @@ ...@@ -71,15 +71,22 @@
71 71
72 <script setup> 72 <script setup>
73 import { ref, reactive, onMounted } from 'vue' 73 import { ref, reactive, onMounted } from 'vue'
74 -import { generateWaterfallData } from '@/utils/mockData'
75 import { useTitle } from '@vueuse/core'; 74 import { useTitle } from '@vueuse/core';
75 +import { useRouter } from 'vue-router'
76 +
77 +// 导入接口
78 +import { getImgStreamAPI } from '@/api/index.js'
76 79
77 useTitle('义工') 80 useTitle('义工')
78 81
82 +const router = useRouter()
83 +
84 +const cid = ref(router.currentRoute.value.query.cid)
85 +
79 // 响应式数据 86 // 响应式数据
80 const loading = ref(false) 87 const loading = ref(false)
81 const finished = ref(false) 88 const finished = ref(false)
82 -const currentPage = ref(1) 89 +const currentPage = ref(0) // API使用0作为起始页码
83 const pageSize = 10 90 const pageSize = 10
84 const allImages = ref([]) 91 const allImages = ref([])
85 const columns = reactive([[], []]) 92 const columns = reactive([[], []])
...@@ -92,21 +99,37 @@ const selectedImage = ref(null) ...@@ -92,21 +99,37 @@ const selectedImage = ref(null)
92 const onLoad = async () => { 99 const onLoad = async () => {
93 loading.value = true 100 loading.value = true
94 101
95 - // 模拟网络延迟
96 - await new Promise(resolve => setTimeout(resolve, 1000))
97 -
98 try { 102 try {
99 - const newData = generateWaterfallData(currentPage.value, pageSize) 103 + // 调用正式接口
100 - 104 + const response = await getImgStreamAPI({
101 - if (newData.length === 0) { 105 + cid: cid.value,
102 - finished.value = true 106 + page: currentPage.value,
107 + limit: pageSize
108 + })
109 +
110 + if (response.code && response.list) {
111 + const newData = response.list.map(item => ({
112 + id: item.id,
113 + src: item.photo,
114 + title: item.post_title,
115 + description: item.post_content,
116 + date: item.post_date,
117 + height: Math.floor(Math.random() * 200) + 200 // 随机高度用于瀑布流布局
118 + }))
119 +
120 + if (newData.length === 0) {
121 + finished.value = true
122 + } else {
123 + allImages.value.push(...newData)
124 + distributeImages(newData)
125 + currentPage.value++
126 + }
103 } else { 127 } else {
104 - allImages.value.push(...newData) 128 + finished.value = true
105 - distributeImages(newData)
106 - currentPage.value++
107 } 129 }
108 } catch (error) { 130 } catch (error) {
109 console.error('加载数据失败:', error) 131 console.error('加载数据失败:', error)
132 + finished.value = true
110 } finally { 133 } finally {
111 loading.value = false 134 loading.value = false
112 } 135 }
...@@ -376,22 +399,22 @@ onMounted(() => { ...@@ -376,22 +399,22 @@ onMounted(() => {
376 max-height: 85vh; 399 max-height: 85vh;
377 border-radius: 0.75rem; 400 border-radius: 0.75rem;
378 } 401 }
379 - 402 +
380 .close-btn { 403 .close-btn {
381 top: 0.75rem; 404 top: 0.75rem;
382 right: 0.75rem; 405 right: 0.75rem;
383 width: 2rem; 406 width: 2rem;
384 height: 2rem; 407 height: 2rem;
385 } 408 }
386 - 409 +
387 .overlay-description { 410 .overlay-description {
388 padding: 1rem; 411 padding: 1rem;
389 } 412 }
390 - 413 +
391 .overlay-title { 414 .overlay-title {
392 font-size: 1.125rem; 415 font-size: 1.125rem;
393 } 416 }
394 - 417 +
395 .overlay-text { 418 .overlay-text {
396 font-size: 0.875rem; 419 font-size: 0.875rem;
397 } 420 }
......