hookehuyr

fix(map_activity): 修复接口字段拼写错误和封面空值处理

- 修复 detail/list 接口字段拼写错误:tittle → title
- 修复 PosterCheckinDetail 页面 API 导入错误
- 添加 cover 字段空值处理,使用默认封面图
- 同步更新 API 文档和 Mock 数据

影响文件:
- src/pages/ActivitiesDetail/index.vue
- src/pages/CheckinMap/index.vue
- src/pages/PosterCheckinDetail/index.vue
- src/utils/mockData.js
- src/api/map_activity.js
- docs/api-specs/map_activity/detail.md
- docs/api-specs/map_activity/list.md

Co-Authored-By: Claude Code <noreply@anthropic.com>
...@@ -41,6 +41,7 @@ paths: ...@@ -41,6 +41,7 @@ paths:
41 in: query 41 in: query
42 description: 活动ID 42 description: 活动ID
43 required: false 43 required: false
44 + example: '834988'
44 schema: 45 schema:
45 type: string 46 type: string
46 responses: 47 responses:
...@@ -62,14 +63,11 @@ paths: ...@@ -62,14 +63,11 @@ paths:
62 type: string 63 type: string
63 title: 地图网址 64 title: 地图网址
64 id: 65 id:
65 - type: string 66 + type: integer
66 title: 活动ID 67 title: 活动ID
67 cover: 68 cover:
68 type: string 69 type: string
69 title: 封面图 70 title: 封面图
70 - tittle:
71 - type: string
72 - title: 标题
73 begin_date: 71 begin_date:
74 type: string 72 type: string
75 title: 开始时间 73 title: 开始时间
...@@ -94,10 +92,13 @@ paths: ...@@ -94,10 +92,13 @@ paths:
94 discount_title: 92 discount_title:
95 type: string 93 type: string
96 title: 打卡点底部优惠标题 94 title: 打卡点底部优惠标题
95 + title:
96 + type: string
97 + title: 标题
97 x-apifox-orders: 98 x-apifox-orders:
98 - id 99 - id
99 - cover 100 - cover
100 - - tittle 101 + - title
101 - begin_date 102 - begin_date
102 - end_date 103 - end_date
103 - is_ended 104 - is_ended
...@@ -113,7 +114,7 @@ paths: ...@@ -113,7 +114,7 @@ paths:
113 - begin_date 114 - begin_date
114 - id 115 - id
115 - cover 116 - cover
116 - - tittle 117 + - title
117 - first_checkin_points 118 - first_checkin_points
118 - required_checkin_count 119 - required_checkin_count
119 - complete_points 120 - complete_points
...@@ -137,7 +138,9 @@ components: ...@@ -137,7 +138,9 @@ components:
137 schemas: {} 138 schemas: {}
138 responses: {} 139 responses: {}
139 securitySchemes: {} 140 securitySchemes: {}
140 -servers: [] 141 +servers:
142 + - url: https://oa-dev.onwall.cn
143 + description: 测试环境
141 security: [] 144 security: []
142 145
143 ``` 146 ```
......
...@@ -58,24 +58,24 @@ paths: ...@@ -58,24 +58,24 @@ paths:
58 type: string 58 type: string
59 title: 地图网址 59 title: 地图网址
60 id: 60 id:
61 - type: string 61 + type: integer
62 title: 活动ID 62 title: 活动ID
63 cover: 63 cover:
64 type: string 64 type: string
65 title: 封面图 65 title: 封面图
66 - tittle:
67 - type: string
68 - title: 标题
69 begin_date: 66 begin_date:
70 type: string 67 type: string
71 title: 开始时间 68 title: 开始时间
72 end_date: 69 end_date:
73 type: string 70 type: string
74 title: 结束时间 71 title: 结束时间
72 + title:
73 + type: string
74 + title: 标题
75 x-apifox-orders: 75 x-apifox-orders:
76 - id 76 - id
77 - cover 77 - cover
78 - - tittle 78 + - title
79 - begin_date 79 - begin_date
80 - end_date 80 - end_date
81 - url 81 - url
...@@ -85,7 +85,7 @@ paths: ...@@ -85,7 +85,7 @@ paths:
85 - begin_date 85 - begin_date
86 - id 86 - id
87 - cover 87 - cover
88 - - tittle 88 + - title
89 x-apifox-orders: 89 x-apifox-orders:
90 - code 90 - code
91 - msg 91 - msg
...@@ -105,7 +105,9 @@ components: ...@@ -105,7 +105,9 @@ components:
105 schemas: {} 105 schemas: {}
106 responses: {} 106 responses: {}
107 securitySchemes: {} 107 securitySchemes: {}
108 -servers: [] 108 +servers:
109 + - url: https://oa-dev.onwall.cn
110 + description: 测试环境
109 security: [] 111 security: []
110 112
111 ``` 113 ```
......
...@@ -34,9 +34,8 @@ export const checkinAPI = params => fn(fetch.post(Api.Checkin, params)) ...@@ -34,9 +34,8 @@ export const checkinAPI = params => fn(fetch.post(Api.Checkin, params))
34 * msg: string; // 消息 34 * msg: string; // 消息
35 * data: { 35 * data: {
36 url: string; // 地图网址 36 url: string; // 地图网址
37 - id: string; // 活动ID 37 + id: integer; // 活动ID
38 cover: string; // 封面图 38 cover: string; // 封面图
39 - tittle: string; // 标题
40 begin_date: string; // 开始时间 39 begin_date: string; // 开始时间
41 end_date: string; // 结束时间 40 end_date: string; // 结束时间
42 is_ended: boolean; // 活动是否已经结束 41 is_ended: boolean; // 活动是否已经结束
...@@ -45,6 +44,7 @@ export const checkinAPI = params => fn(fetch.post(Api.Checkin, params)) ...@@ -45,6 +44,7 @@ export const checkinAPI = params => fn(fetch.post(Api.Checkin, params))
45 required_checkin_count: integer; // 需要打卡几次,才能完成活动 44 required_checkin_count: integer; // 需要打卡几次,才能完成活动
46 complete_points: integer; // 完成活动获得多少积分 45 complete_points: integer; // 完成活动获得多少积分
47 discount_title: string; // 打卡点底部优惠标题 46 discount_title: string; // 打卡点底部优惠标题
47 + title: string; // 标题
48 * }; 48 * };
49 * }>} 49 * }>}
50 */ 50 */
...@@ -76,11 +76,11 @@ export const isCheckedAPI = params => fn(fetch.get(Api.IsChecked, params)) ...@@ -76,11 +76,11 @@ export const isCheckedAPI = params => fn(fetch.get(Api.IsChecked, params))
76 * msg: string; // 消息 76 * msg: string; // 消息
77 * data: Array<{ 77 * data: Array<{
78 url: string; // 地图网址 78 url: string; // 地图网址
79 - id: string; // 活动ID 79 + id: integer; // 活动ID
80 cover: string; // 封面图 80 cover: string; // 封面图
81 - tittle: string; // 标题
82 begin_date: string; // 开始时间 81 begin_date: string; // 开始时间
83 end_date: string; // 结束时间 82 end_date: string; // 结束时间
83 + title: string; // 标题
84 * }>; 84 * }>;
85 * }>} 85 * }>}
86 */ 86 */
...@@ -118,7 +118,7 @@ export const listAPI = params => fn(fetch.get(Api.List, params)) ...@@ -118,7 +118,7 @@ export const listAPI = params => fn(fetch.get(Api.List, params))
118 * }; 118 * };
119 * }>} 119 * }>}
120 */ 120 */
121 -export const getPosterDetailAPI = params => fn(fetch.get(Api.Poster, params)) 121 +export const posterAPI = params => fn(fetch.get(Api.Poster, params))
122 122
123 /** 123 /**
124 * @description 上传海报背景 124 * @description 上传海报背景
......
...@@ -964,11 +964,11 @@ const transformApiDataToActivityData = apiData => { ...@@ -964,11 +964,11 @@ const transformApiDataToActivityData = apiData => {
964 ] 964 ]
965 965
966 return { 966 return {
967 - title: apiData.tittle || '活动标题', 967 + title: apiData.title || '活动标题',
968 subtitle: '探索城市魅力,感受时尚脉搏', 968 subtitle: '探索城市魅力,感受时尚脉搏',
969 dateRange: dateRange, 969 dateRange: dateRange,
970 posterUrl: apiData.cover || defaultPoster.value, 970 posterUrl: apiData.cover || defaultPoster.value,
971 - description: `欢迎参加${apiData.tittle}活动!`, 971 + description: `欢迎参加${apiData.title}活动!`,
972 rules: rules, 972 rules: rules,
973 rewards: rewards, 973 rewards: rewards,
974 } 974 }
...@@ -1000,9 +1000,12 @@ const fetchActivityDetail = async () => { ...@@ -1000,9 +1000,12 @@ const fetchActivityDetail = async () => {
1000 if (transformedData) { 1000 if (transformedData) {
1001 activityData.value = transformedData 1001 activityData.value = transformedData
1002 1002
1003 - // 更新默认海报图 1003 + // 更新默认海报图:如果 cover 为空,使用默认封面
1004 - if (response.data.cover) { 1004 + if (response.data.cover && response.data.cover.trim() !== '') {
1005 defaultPoster.value = response.data.cover 1005 defaultPoster.value = response.data.cover
1006 + } else {
1007 + // cover 为空,保持默认封面不变
1008 + console.log('[ActivitiesCover] cover 为空,使用默认封面图')
1006 } 1009 }
1007 1010
1008 // 更新活动状态 1011 // 更新活动状态
......
...@@ -44,6 +44,10 @@ import { useLoad } from '@tarojs/taro' ...@@ -44,6 +44,10 @@ import { useLoad } from '@tarojs/taro'
44 // ⚠️ MOCK 数据开关 - 开发环境使用 mock 数据,生产环境使用真实 API 44 // ⚠️ MOCK 数据开关 - 开发环境使用 mock 数据,生产环境使用真实 API
45 const USE_MOCK_DATA = process.env.NODE_ENV === 'development' 45 const USE_MOCK_DATA = process.env.NODE_ENV === 'development'
46 46
47 +// 默认封面图
48 +const DEFAULT_COVER =
49 + 'https://cdn.ipadbiz.cn/lls_prog/images/welcome_8.jpg?imageMogr2/strip/quality/60'
50 +
47 /** 51 /**
48 * 便民地图列表数据 52 * 便民地图列表数据
49 */ 53 */
...@@ -58,10 +62,11 @@ const loading = ref(false) ...@@ -58,10 +62,11 @@ const loading = ref(false)
58 const formatMapList = list => { 62 const formatMapList = list => {
59 return list.map(item => ({ 63 return list.map(item => ({
60 id: item.id, 64 id: item.id,
61 - title: item.tittle, // API 返回的是 tittle,映射为 title 65 + title: item.title,
62 - cover: item.cover, 66 + // 如果 cover 为空,使用默认封面图
67 + cover: item.cover && item.cover.trim() !== '' ? item.cover : DEFAULT_COVER,
63 timeRange: `${item.begin_date}~${item.end_date}`, 68 timeRange: `${item.begin_date}~${item.end_date}`,
64 - activityId: item.id, // 使用 id 作为 activityId 69 + activityId: item.id,
65 })) 70 }))
66 } 71 }
67 72
......
...@@ -167,7 +167,7 @@ import { Left, Right } from '@nutui/icons-vue-taro' ...@@ -167,7 +167,7 @@ import { Left, Right } from '@nutui/icons-vue-taro'
167 import PosterBuilder from '@/components/PosterBuilder/index.vue' 167 import PosterBuilder from '@/components/PosterBuilder/index.vue'
168 import BASE_URL from '@/utils/config' 168 import BASE_URL from '@/utils/config'
169 // 导入获取海报详情的API 169 // 导入获取海报详情的API
170 -import { getPosterDetailAPI, savePosterBackgroundAPI } from '@/api/map_activity' 170 +import { posterAPI, savePosterBackgroundAPI } from '@/api/map_activity'
171 // 默认背景图 171 // 默认背景图
172 const defaultBackground = 172 const defaultBackground =
173 'https://cdn.ipadbiz.cn/lls_prog/images/%E6%B5%B7%E6%8A%A5%E9%BB%98%E8%AE%A4%E8%83%8C%E6%99%AF%E5%9B%BE1.png?imageMogr2/strip/quality/60' 173 'https://cdn.ipadbiz.cn/lls_prog/images/%E6%B5%B7%E6%8A%A5%E9%BB%98%E8%AE%A4%E8%83%8C%E6%99%AF%E5%9B%BE1.png?imageMogr2/strip/quality/60'
...@@ -209,7 +209,7 @@ const fetchPosterDetail = async () => { ...@@ -209,7 +209,7 @@ const fetchPosterDetail = async () => {
209 // 小程序版本。正式版为 "release",体验版为 "trial"。默认是正式版 209 // 小程序版本。正式版为 "release",体验版为 "trial"。默认是正式版
210 const env_version = envVersion === 'release' ? 'release' : 'trial' 210 const env_version = envVersion === 'release' ? 'release' : 'trial'
211 211
212 - const response = await getPosterDetailAPI({ env_version }) 212 + const response = await posterAPI({ env_version })
213 213
214 if (response.code === 1) { 214 if (response.code === 1) {
215 apiData.value = response.data 215 apiData.value = response.data
......
...@@ -73,7 +73,7 @@ function generateMapActivityItem(id) { ...@@ -73,7 +73,7 @@ function generateMapActivityItem(id) {
73 73
74 return { 74 return {
75 id: String(id), 75 id: String(id),
76 - tittle: activityName, 76 + title: activityName,
77 cover: randomImage(400, 300, id), 77 cover: randomImage(400, 300, id),
78 begin_date: formatDate(startDate), 78 begin_date: formatDate(startDate),
79 end_date: formatDate(endDate), 79 end_date: formatDate(endDate),
...@@ -255,7 +255,7 @@ export const mockMapActivityDetail = () => { ...@@ -255,7 +255,7 @@ export const mockMapActivityDetail = () => {
255 url: 'https://example.com/map', 255 url: 'https://example.com/map',
256 id: '1', 256 id: '1',
257 cover: randomImage(750, 500, 10), 257 cover: randomImage(750, 500, 10),
258 - tittle: '重阳登高打卡', 258 + title: '重阳登高打卡',
259 begin_date: '2025.09.06', 259 begin_date: '2025.09.06',
260 end_date: '2025.10.31', 260 end_date: '2025.10.31',
261 is_ended: false, 261 is_ended: false,
......