hookehuyr

refactor(map_activity): 重命名 posterAPI 为 getPosterDetailAPI

- 将 posterAPI 重命名为 getPosterDetailAPI,命名更清晰
- 修复 PosterCheckin 页面的 API 导入路径(@/api/map → @/api/map_activity)
- 更新 CHANGELOG 记录海报接口联调功能

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
...@@ -26,7 +26,7 @@ export const checkinAPI = params => fn(fetch.post(Api.Checkin, params)) ...@@ -26,7 +26,7 @@ export const checkinAPI = params => fn(fetch.post(Api.Checkin, params))
26 26
27 /** 27 /**
28 * @description 地图活动详情 28 * @description 地图活动详情
29 - * @remark 29 + * @remark
30 * @param {Object} params 请求参数 30 * @param {Object} params 请求参数
31 * @param {string} params.id (可选) 活动ID 31 * @param {string} params.id (可选) 活动ID
32 * @returns {Promise<{ 32 * @returns {Promise<{
...@@ -52,10 +52,10 @@ export const detailAPI = params => fn(fetch.get(Api.Detail, params)) ...@@ -52,10 +52,10 @@ export const detailAPI = params => fn(fetch.get(Api.Detail, params))
52 52
53 /** 53 /**
54 * @description 是否已经打卡 54 * @description 是否已经打卡
55 - * @remark 55 + * @remark
56 * @param {Object} params 请求参数 56 * @param {Object} params 请求参数
57 * @param {string} params.detail_id (可选) 打卡点ID 57 * @param {string} params.detail_id (可选) 打卡点ID
58 - * @param {string} params.openid (可选) 58 + * @param {string} params.openid (可选)
59 * @param {string} params.activity_id (可选) 活动ID 59 * @param {string} params.activity_id (可选) 活动ID
60 * @returns {Promise<{ 60 * @returns {Promise<{
61 * code: number; // 状态码 61 * code: number; // 状态码
...@@ -69,7 +69,7 @@ export const isCheckedAPI = params => fn(fetch.get(Api.IsChecked, params)) ...@@ -69,7 +69,7 @@ export const isCheckedAPI = params => fn(fetch.get(Api.IsChecked, params))
69 69
70 /** 70 /**
71 * @description 地图活动列表 71 * @description 地图活动列表
72 - * @remark 72 + * @remark
73 * @param {Object} params 请求参数 73 * @param {Object} params 请求参数
74 * @returns {Promise<{ 74 * @returns {Promise<{
75 * code: number; // 状态码 75 * code: number; // 状态码
...@@ -88,7 +88,7 @@ export const listAPI = params => fn(fetch.get(Api.List, params)) ...@@ -88,7 +88,7 @@ export const listAPI = params => fn(fetch.get(Api.List, params))
88 88
89 /** 89 /**
90 * @description 获取海报 90 * @description 获取海报
91 - * @remark 91 + * @remark
92 * @param {Object} params 请求参数 92 * @param {Object} params 请求参数
93 * @param {string} params.activity_id (可选) 活动ID 93 * @param {string} params.activity_id (可选) 活动ID
94 * @param {string} params.detail_id (可选) 关卡ID 94 * @param {string} params.detail_id (可选) 关卡ID
...@@ -101,8 +101,8 @@ export const listAPI = params => fn(fetch.get(Api.List, params)) ...@@ -101,8 +101,8 @@ export const listAPI = params => fn(fetch.get(Api.List, params))
101 id: integer; // 关卡ID 101 id: integer; // 关卡ID
102 name: string; // 关卡名称 102 name: string; // 关卡名称
103 background_url: string; // 关卡背景图 103 background_url: string; // 关卡背景图
104 - main_slogan: string; // 104 + main_slogan: string; //
105 - sub_slogan: string; // 105 + sub_slogan: string; //
106 is_checked: boolean; // 是否已经打卡 106 is_checked: boolean; // 是否已经打卡
107 }>; 107 }>;
108 family: { 108 family: {
...@@ -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 posterAPI = params => fn(fetch.get(Api.Poster, params)) 121 +export const getPosterDetailAPI = params => fn(fetch.get(Api.Poster, params))
122 122
123 /** 123 /**
124 * @description 上传海报背景 124 * @description 上传海报背景
......
...@@ -20,7 +20,10 @@ ...@@ -20,7 +20,10 @@
20 <!-- 正常内容 --> 20 <!-- 正常内容 -->
21 <template v-else> 21 <template v-else>
22 <!-- 活动信息区域 --> 22 <!-- 活动信息区域 -->
23 - <view v-if="pageState === 'normal' || pageState === 'no-checkin'" class="bg-white mx-4 mt-4 mb-2 rounded-lg shadow-sm p-4"> 23 + <view
24 + v-if="pageState === 'normal' || pageState === 'no-checkin'"
25 + class="bg-white mx-4 mt-4 mb-2 rounded-lg shadow-sm p-4"
26 + >
24 <!-- 活动主题 --> 27 <!-- 活动主题 -->
25 <view class="text-lg font-bold text-gray-800 mb-2"> 28 <view class="text-lg font-bold text-gray-800 mb-2">
26 {{ activityInfo.title }} 29 {{ activityInfo.title }}
...@@ -37,24 +40,24 @@ ...@@ -37,24 +40,24 @@
37 > 40 >
38 </view> 41 </view>
39 </view> 42 </view>
40 - <text class="text-xs text-gray-600">{{ activityInfo.completedCount }}/{{ activityInfo.totalCount }}</text> 43 + <text class="text-xs text-gray-600"
44 + >{{ activityInfo.completedCount }}/{{ activityInfo.totalCount }}</text
45 + >
41 </view> 46 </view>
42 47
43 <!-- 活动截止日期 --> 48 <!-- 活动截止日期 -->
44 - <view class="text-sm text-gray-500"> 49 + <view class="text-sm text-gray-500"> 活动截止日期:{{ activityInfo.endDate }} </view>
45 - 活动截止日期:{{ activityInfo.endDate }}
46 - </view>
47 </view> 50 </view>
48 51
49 <!-- 海报预览区域 - 正常状态 --> 52 <!-- 海报预览区域 - 正常状态 -->
50 - <view v-if="pageState === 'normal'" class="flex-1 mx-4 relative" style="overflow: visible; padding-bottom: 110rpx;"> 53 + <view
54 + v-if="pageState === 'normal'"
55 + class="flex-1 mx-4 relative"
56 + style="overflow: visible; padding-bottom: 110rpx"
57 + >
51 <view class="h-full relative flex items-center justify-center"> 58 <view class="h-full relative flex items-center justify-center">
52 <view v-if="currentPoster.path" class="w-full h-full relative"> 59 <view v-if="currentPoster.path" class="w-full h-full relative">
53 - <image 60 + <image :src="currentPoster.path" mode="widthFix" class="w-full h-full" />
54 - :src="currentPoster.path"
55 - mode="widthFix"
56 - class="w-full h-full"
57 - />
58 <!-- 打卡点标题 --> 61 <!-- 打卡点标题 -->
59 <!-- <view class="absolute bottom-2 left-2 bg-blue-500 text-white text-xs px-2 py-1 rounded"> 62 <!-- <view class="absolute bottom-2 left-2 bg-blue-500 text-white text-xs px-2 py-1 rounded">
60 {{ posterList[currentPosterIndex]?.title || '海报生成中' }} 63 {{ posterList[currentPosterIndex]?.title || '海报生成中' }}
...@@ -69,8 +72,12 @@ ...@@ -69,8 +72,12 @@
69 <!-- 左箭头按钮 --> 72 <!-- 左箭头按钮 -->
70 <view 73 <view
71 class="absolute top-1/2 transform -translate-y-1/2 w-10 h-10 rounded-full flex items-center justify-center transition-all duration-200 z-10" 74 class="absolute top-1/2 transform -translate-y-1/2 w-10 h-10 rounded-full flex items-center justify-center transition-all duration-200 z-10"
72 - :class="currentPosterIndex > 0 ? 'bg-orange-400 text-white shadow-lg' : 'bg-gray-300 text-gray-500'" 75 + :class="
73 - style="left: -20rpx;" 76 + currentPosterIndex > 0
77 + ? 'bg-orange-400 text-white shadow-lg'
78 + : 'bg-gray-300 text-gray-500'
79 + "
80 + style="left: -20rpx"
74 @tap="previousPoster" 81 @tap="previousPoster"
75 > 82 >
76 <Left size="16"></Left> 83 <Left size="16"></Left>
...@@ -79,8 +86,12 @@ ...@@ -79,8 +86,12 @@
79 <!-- 右箭头按钮 --> 86 <!-- 右箭头按钮 -->
80 <view 87 <view
81 class="absolute top-1/2 transform -translate-y-1/2 w-10 h-10 rounded-full flex items-center justify-center transition-all duration-200 z-10" 88 class="absolute top-1/2 transform -translate-y-1/2 w-10 h-10 rounded-full flex items-center justify-center transition-all duration-200 z-10"
82 - :class="currentPosterIndex < posterList.length - 1 ? 'bg-orange-400 text-white shadow-lg' : 'bg-gray-300 text-gray-500'" 89 + :class="
83 - style="right: -20rpx;" 90 + currentPosterIndex < posterList.length - 1
91 + ? 'bg-orange-400 text-white shadow-lg'
92 + : 'bg-gray-300 text-gray-500'
93 + "
94 + style="right: -20rpx"
84 @tap="nextPoster" 95 @tap="nextPoster"
85 > 96 >
86 <Right size="16"></Right> 97 <Right size="16"></Right>
...@@ -97,7 +108,11 @@ ...@@ -97,7 +108,11 @@
97 </view> 108 </view>
98 109
99 <!-- 底部操作按钮 - 仅在正常状态显示 --> 110 <!-- 底部操作按钮 - 仅在正常状态显示 -->
100 - <view v-if="pageState === 'normal'" class="bg-white border-t border-gray-200 p-4 safe-area-bottom z-50" style="position: fixed; bottom: 0; left: 0; right: 0;"> 111 + <view
112 + v-if="pageState === 'normal'"
113 + class="bg-white border-t border-gray-200 p-4 safe-area-bottom z-50"
114 + style="position: fixed; bottom: 0; left: 0; right: 0"
115 + >
101 <view class="flex gap-4"> 116 <view class="flex gap-4">
102 <view 117 <view
103 class="flex-1 bg-gradient-to-r from-orange-400 to-orange-500 text-white text-sm py-3 px-6 rounded-lg font-medium shadow-lg active:scale-95 transition-transform duration-150 flex items-center justify-center gap-2" 118 class="flex-1 bg-gradient-to-r from-orange-400 to-orange-500 text-white text-sm py-3 px-6 rounded-lg font-medium shadow-lg active:scale-95 transition-transform duration-150 flex items-center justify-center gap-2"
...@@ -107,11 +122,19 @@ ...@@ -107,11 +122,19 @@
107 </view> 122 </view>
108 <view 123 <view
109 class="flex-1 text-white py-3 px-6 rounded-lg font-medium text-sm shadow-lg active:scale-95 transition-transform duration-150 flex items-center justify-center gap-2" 124 class="flex-1 text-white py-3 px-6 rounded-lg font-medium text-sm shadow-lg active:scale-95 transition-transform duration-150 flex items-center justify-center gap-2"
110 - :class="posterPath ? 'bg-gradient-to-r from-green-400 to-green-500' : (posterGenerateFailed ? 'bg-gradient-to-r from-orange-400 to-orange-500' : 'bg-gray-400')" 125 + :class="
126 + posterPath
127 + ? 'bg-gradient-to-r from-green-400 to-green-500'
128 + : posterGenerateFailed
129 + ? 'bg-gradient-to-r from-orange-400 to-orange-500'
130 + : 'bg-gray-400'
131 + "
111 @click="handlePosterAction" 132 @click="handlePosterAction"
112 :disabled="!posterPath && !posterGenerateFailed" 133 :disabled="!posterPath && !posterGenerateFailed"
113 > 134 >
114 - <text>{{ posterPath ? '保存海报' : (posterGenerateFailed ? '重新生成' : '生成中...') }}</text> 135 + <text>{{
136 + posterPath ? '保存海报' : posterGenerateFailed ? '重新生成' : '生成中...'
137 + }}</text>
115 </view> 138 </view>
116 </view> 139 </view>
117 </view> 140 </view>
...@@ -134,7 +157,6 @@ ...@@ -134,7 +157,6 @@
134 :show-index="false" 157 :show-index="false"
135 @close="closePreview" 158 @close="closePreview"
136 /> 159 />
137 -
138 </view> 160 </view>
139 </template> 161 </template>
140 162
...@@ -145,9 +167,10 @@ import { Left, Right } from '@nutui/icons-vue-taro' ...@@ -145,9 +167,10 @@ import { Left, Right } from '@nutui/icons-vue-taro'
145 import PosterBuilder from '@/components/PosterBuilder/index.vue' 167 import PosterBuilder from '@/components/PosterBuilder/index.vue'
146 import BASE_URL from '@/utils/config' 168 import BASE_URL from '@/utils/config'
147 // 导入获取海报详情的API 169 // 导入获取海报详情的API
148 -import { getPosterDetailAPI, savePosterBackgroundAPI } from '@/api/map' 170 +import { getPosterDetailAPI, savePosterBackgroundAPI } from '@/api/map_activity'
149 // 默认背景图 171 // 默认背景图
150 -const defaultBackground = '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' 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'
151 174
152 // 页面状态 175 // 页面状态
153 const posterPath = ref('') // 生成的海报路径 176 const posterPath = ref('') // 生成的海报路径
...@@ -181,10 +204,10 @@ const fetchPosterDetail = async () => { ...@@ -181,10 +204,10 @@ const fetchPosterDetail = async () => {
181 isLoading.value = true 204 isLoading.value = true
182 apiError.value = null 205 apiError.value = null
183 206
184 - const accountInfo = wx.getAccountInfoSync(); 207 + const accountInfo = wx.getAccountInfoSync()
185 - const envVersion = accountInfo.miniProgram.envVersion; 208 + const envVersion = accountInfo.miniProgram.envVersion
186 // 小程序版本。正式版为 "release",体验版为 "trial"。默认是正式版 209 // 小程序版本。正式版为 "release",体验版为 "trial"。默认是正式版
187 - const env_version = envVersion === 'release' ? 'release' : 'trial'; 210 + const env_version = envVersion === 'release' ? 'release' : 'trial'
188 211
189 const response = await getPosterDetailAPI({ env_version }) 212 const response = await getPosterDetailAPI({ env_version })
190 213
...@@ -200,7 +223,6 @@ const fetchPosterDetail = async () => { ...@@ -200,7 +223,6 @@ const fetchPosterDetail = async () => {
200 223
201 // 根据pageParams.id设置当前海报索引 224 // 根据pageParams.id设置当前海报索引
202 setCurrentPosterIndex() 225 setCurrentPosterIndex()
203 -
204 } else { 226 } else {
205 apiError.value = response.msg || '获取海报详情失败' 227 apiError.value = response.msg || '获取海报详情失败'
206 console.error('获取海报详情失败:', response.msg) 228 console.error('获取海报详情失败:', response.msg)
...@@ -217,7 +239,9 @@ const fetchPosterDetail = async () => { ...@@ -217,7 +239,9 @@ const fetchPosterDetail = async () => {
217 * 根据API数据更新活动信息 239 * 根据API数据更新活动信息
218 */ 240 */
219 const updateActivityInfo = () => { 241 const updateActivityInfo = () => {
220 - if (!apiData.value) return 242 + if (!apiData.value) {
243 + return
244 + }
221 245
222 const { title, end_date, details, show_detail_index } = apiData.value 246 const { title, end_date, details, show_detail_index } = apiData.value
223 247
...@@ -225,7 +249,7 @@ const updateActivityInfo = () => { ...@@ -225,7 +249,7 @@ const updateActivityInfo = () => {
225 const checkPoints = details.map((detail, index) => ({ 249 const checkPoints = details.map((detail, index) => ({
226 id: detail.id, 250 id: detail.id,
227 name: detail.name, 251 name: detail.name,
228 - completed: detail.is_checked === true 252 + completed: detail.is_checked === true,
229 })) 253 }))
230 254
231 // 计算已完成数量 255 // 计算已完成数量
...@@ -237,7 +261,7 @@ const updateActivityInfo = () => { ...@@ -237,7 +261,7 @@ const updateActivityInfo = () => {
237 completedCount, 261 completedCount,
238 totalCount: checkPoints.length, 262 totalCount: checkPoints.length,
239 endDate: end_date || '', 263 endDate: end_date || '',
240 - showDetailIndex: show_detail_index || 0 264 + showDetailIndex: show_detail_index || 0,
241 } 265 }
242 } 266 }
243 267
...@@ -245,14 +269,14 @@ const updateActivityInfo = () => { ...@@ -245,14 +269,14 @@ const updateActivityInfo = () => {
245 * 根据API数据更新海报列表 269 * 根据API数据更新海报列表
246 */ 270 */
247 const updatePosterList = () => { 271 const updatePosterList = () => {
248 - if (!apiData.value) return 272 + if (!apiData.value) {
273 + return
274 + }
249 275
250 const { details, family, qrcode_url } = apiData.value 276 const { details, family, qrcode_url } = apiData.value
251 277
252 // 只显示is_checked为真的关卡 278 // 只显示is_checked为真的关卡
253 - const checkedDetails = details.filter(detail => 279 + const checkedDetails = details.filter(detail => detail.is_checked === true)
254 - detail.is_checked === true
255 - )
256 280
257 posterList.value = checkedDetails.map((detail, index) => ({ 281 posterList.value = checkedDetails.map((detail, index) => ({
258 id: detail.id, 282 id: detail.id,
...@@ -262,22 +286,28 @@ const updatePosterList = () => { ...@@ -262,22 +286,28 @@ const updatePosterList = () => {
262 backgroundImage: detail.background_url || defaultBackground, 286 backgroundImage: detail.background_url || defaultBackground,
263 // 海报内容数据 287 // 海报内容数据
264 user: { 288 user: {
265 - avatar: family?.avatar_url || 'https://cdn.ipadbiz.cn/lls_prog/images/%E5%85%A8%E5%AE%B6%E7%A6%8F3_%E5%89%AF%E6%9C%AC.jpg?imageMogr2/strip/quality/60', 289 + avatar:
266 - nickname: '用户昵称' // 默认昵称,后续可从用户信息获取 290 + family?.avatar_url ||
291 + 'https://cdn.ipadbiz.cn/lls_prog/images/%E5%85%A8%E5%AE%B6%E7%A6%8F3_%E5%89%AF%E6%9C%AC.jpg?imageMogr2/strip/quality/60',
292 + nickname: '用户昵称', // 默认昵称,后续可从用户信息获取
267 }, 293 },
268 family: { 294 family: {
269 name: family?.name || '我的家庭', 295 name: family?.name || '我的家庭',
270 - description: '' 296 + description: '',
271 }, 297 },
272 activity: { 298 activity: {
273 - logo: detail.main_slogan || 'https://cdn.ipadbiz.cn/lls_prog/images/%E6%B5%B7%E6%8A%A5%E5%B7%A6%E4%B8%8A%E8%A7%92logo.png?imageMogr2/strip/quality/60', 299 + logo:
300 + detail.main_slogan ||
301 + 'https://cdn.ipadbiz.cn/lls_prog/images/%E6%B5%B7%E6%8A%A5%E5%B7%A6%E4%B8%8A%E8%A7%92logo.png?imageMogr2/strip/quality/60',
274 }, 302 },
275 level: { 303 level: {
276 - logo: detail.sub_slogan || 'https://cdn.ipadbiz.cn/lls_prog/images/%E6%B5%B7%E6%8A%A5%E5%8F%B3%E4%B8%8B%E8%A7%92icon.png?imageMogr2/strip/quality/60', 304 + logo:
305 + detail.sub_slogan ||
306 + 'https://cdn.ipadbiz.cn/lls_prog/images/%E6%B5%B7%E6%8A%A5%E5%8F%B3%E4%B8%8B%E8%A7%92icon.png?imageMogr2/strip/quality/60',
277 name: detail.name || '海报打卡活动', 307 name: detail.name || '海报打卡活动',
278 }, 308 },
279 qrcode: qrcode_url, 309 qrcode: qrcode_url,
280 - qrcodeDesc: '长按识别,来,我们一起打卡!' 310 + qrcodeDesc: '长按识别,来,我们一起打卡!',
281 })) 311 }))
282 } 312 }
283 313
...@@ -292,8 +322,8 @@ const setCurrentPosterIndex = () => { ...@@ -292,8 +322,8 @@ const setCurrentPosterIndex = () => {
292 322
293 // 如果有指定的ID,查找对应的海报索引 323 // 如果有指定的ID,查找对应的海报索引
294 if (pageParams.value.id) { 324 if (pageParams.value.id) {
295 - const targetIndex = posterList.value.findIndex(poster => 325 + const targetIndex = posterList.value.findIndex(
296 - poster.checkPointId.toString() === pageParams.value.id.toString() 326 + poster => poster.checkPointId.toString() === pageParams.value.id.toString()
297 ) 327 )
298 328
299 if (targetIndex !== -1) { 329 if (targetIndex !== -1) {
...@@ -314,7 +344,7 @@ const activityInfo = ref({ ...@@ -314,7 +344,7 @@ const activityInfo = ref({
314 completedCount: 0, 344 completedCount: 0,
315 totalCount: 0, 345 totalCount: 0,
316 endDate: '', 346 endDate: '',
317 - showDetailIndex: 0 347 + showDetailIndex: 0,
318 }) 348 })
319 349
320 // 海报数据列表 - 将由API数据填充 350 // 海报数据列表 - 将由API数据填充
...@@ -322,7 +352,12 @@ const posterList = ref([]) ...@@ -322,7 +352,12 @@ const posterList = ref([])
322 352
323 // 数据状态检查 353 // 数据状态检查
324 const hasActivityInfo = computed(() => { 354 const hasActivityInfo = computed(() => {
325 - return activityInfo.value && activityInfo.value.title && activityInfo.value.checkPoints && activityInfo.value.checkPoints.length > 0 355 + return (
356 + activityInfo.value &&
357 + activityInfo.value.title &&
358 + activityInfo.value.checkPoints &&
359 + activityInfo.value.checkPoints.length > 0
360 + )
326 }) 361 })
327 362
328 const hasCheckinInfo = computed(() => { 363 const hasCheckinInfo = computed(() => {
...@@ -340,8 +375,6 @@ const pageState = computed(() => { ...@@ -340,8 +375,6 @@ const pageState = computed(() => {
340 return 'normal' // 正常状态 375 return 'normal' // 正常状态
341 }) 376 })
342 377
343 -
344 -
345 // 当前海报 378 // 当前海报
346 const currentPoster = computed(() => { 379 const currentPoster = computed(() => {
347 return posterList.value[currentPosterIndex.value] || { path: '', title: '' } 380 return posterList.value[currentPosterIndex.value] || { path: '', title: '' }
...@@ -350,7 +383,9 @@ const currentPoster = computed(() => { ...@@ -350,7 +383,9 @@ const currentPoster = computed(() => {
350 // 当前海报的内容数据 383 // 当前海报的内容数据
351 const currentMockData = computed(() => { 384 const currentMockData = computed(() => {
352 const currentPoster = posterList.value[currentPosterIndex.value] 385 const currentPoster = posterList.value[currentPosterIndex.value]
353 - if (!currentPoster) return null 386 + if (!currentPoster) {
387 + return null
388 + }
354 389
355 return { 390 return {
356 user: currentPoster.user, 391 user: currentPoster.user,
...@@ -358,7 +393,7 @@ const currentMockData = computed(() => { ...@@ -358,7 +393,7 @@ const currentMockData = computed(() => {
358 activity: currentPoster.activity, 393 activity: currentPoster.activity,
359 level: currentPoster.level, 394 level: currentPoster.level,
360 qrcode: currentPoster.qrcode, 395 qrcode: currentPoster.qrcode,
361 - qrcodeDesc: currentPoster.qrcodeDesc 396 + qrcodeDesc: currentPoster.qrcodeDesc,
362 } 397 }
363 }) 398 })
364 399
...@@ -370,7 +405,10 @@ const currentPosterHasCustomBackground = computed(() => { ...@@ -370,7 +405,10 @@ const currentPosterHasCustomBackground = computed(() => {
370 // 海报配置 405 // 海报配置
371 const posterConfig = computed(() => { 406 const posterConfig = computed(() => {
372 const currentPosterData = posterList.value[currentPosterIndex.value] 407 const currentPosterData = posterList.value[currentPosterIndex.value]
373 - const bgImage = backgroundImages.value[currentPosterIndex.value] || currentPosterData?.backgroundImage || defaultBackground 408 + const bgImage =
409 + backgroundImages.value[currentPosterIndex.value] ||
410 + currentPosterData?.backgroundImage ||
411 + defaultBackground
374 412
375 return { 413 return {
376 width: 600, // 从750减少到600,减小Canvas尺寸以控制文件大小 414 width: 600, // 从750减少到600,减小Canvas尺寸以控制文件大小
...@@ -386,7 +424,7 @@ const posterConfig = computed(() => { ...@@ -386,7 +424,7 @@ const posterConfig = computed(() => {
386 width: 600, // 按比例调整 (750 * 0.8 = 600) 424 width: 600, // 按比例调整 (750 * 0.8 = 600)
387 height: 880, // 按比例调整 (1100 * 0.8 = 880) 425 height: 880, // 按比例调整 (1100 * 0.8 = 880)
388 url: bgImage, 426 url: bgImage,
389 - zIndex: 0 427 + zIndex: 0,
390 }, 428 },
391 // 用户头像 429 // 用户头像
392 { 430 {
...@@ -396,7 +434,7 @@ const posterConfig = computed(() => { ...@@ -396,7 +434,7 @@ const posterConfig = computed(() => {
396 height: 104, // 按比例调整 (130 * 0.8 = 104) 434 height: 104, // 按比例调整 (130 * 0.8 = 104)
397 url: currentMockData.value.user.avatar, 435 url: currentMockData.value.user.avatar,
398 borderRadius: 52, // 按比例调整 (65 * 0.8 = 52) 436 borderRadius: 52, // 按比例调整 (65 * 0.8 = 52)
399 - zIndex: 2 437 + zIndex: 2,
400 }, 438 },
401 // 活动logo 439 // 活动logo
402 { 440 {
...@@ -405,7 +443,7 @@ const posterConfig = computed(() => { ...@@ -405,7 +443,7 @@ const posterConfig = computed(() => {
405 width: 200, // 按比例调整 (250 * 0.8 = 200) 443 width: 200, // 按比例调整 (250 * 0.8 = 200)
406 height: 64, // 按比例调整 (80 * 0.8 = 64) 444 height: 64, // 按比例调整 (80 * 0.8 = 64)
407 url: currentMockData.value.activity.logo, 445 url: currentMockData.value.activity.logo,
408 - zIndex: 2 446 + zIndex: 2,
409 }, 447 },
410 // 关卡徽章 448 // 关卡徽章
411 { 449 {
...@@ -414,7 +452,7 @@ const posterConfig = computed(() => { ...@@ -414,7 +452,7 @@ const posterConfig = computed(() => {
414 width: 304, // 按比例调整 (380 * 0.8 = 304) 452 width: 304, // 按比例调整 (380 * 0.8 = 304)
415 height: 80, // 按比例调整 (100 * 0.8 = 80) 453 height: 80, // 按比例调整 (100 * 0.8 = 80)
416 url: currentMockData.value.level.logo, 454 url: currentMockData.value.level.logo,
417 - zIndex: 2 455 + zIndex: 2,
418 }, 456 },
419 // 小程序码 457 // 小程序码
420 { 458 {
...@@ -423,8 +461,8 @@ const posterConfig = computed(() => { ...@@ -423,8 +461,8 @@ const posterConfig = computed(() => {
423 width: 144, // 按比例调整 (180 * 0.8 = 144) 461 width: 144, // 按比例调整 (180 * 0.8 = 144)
424 height: 144, // 按比例调整 (180 * 0.8 = 144) 462 height: 144, // 按比例调整 (180 * 0.8 = 144)
425 url: currentMockData.value.qrcode, 463 url: currentMockData.value.qrcode,
426 - zIndex: 1 464 + zIndex: 1,
427 - } 465 + },
428 ], 466 ],
429 texts: [ 467 texts: [
430 // 家庭名称 468 // 家庭名称
...@@ -440,7 +478,7 @@ const posterConfig = computed(() => { ...@@ -440,7 +478,7 @@ const posterConfig = computed(() => {
440 shadowOffsetX: 2, 478 shadowOffsetX: 2,
441 shadowOffsetY: 2, 479 shadowOffsetY: 2,
442 shadowBlur: 4, 480 shadowBlur: 4,
443 - zIndex: 2 481 + zIndex: 2,
444 }, 482 },
445 // 家庭描述 483 // 家庭描述
446 // { 484 // {
...@@ -467,7 +505,7 @@ const posterConfig = computed(() => { ...@@ -467,7 +505,7 @@ const posterConfig = computed(() => {
467 lineNum: 2, 505 lineNum: 2,
468 width: 352, // 按比例调整 (440 * 0.8 = 352) 506 width: 352, // 按比例调整 (440 * 0.8 = 352)
469 textAlign: 'left', 507 textAlign: 'left',
470 - zIndex: 1 508 + zIndex: 1,
471 }, 509 },
472 // 关卡描述 510 // 关卡描述
473 { 511 {
...@@ -480,7 +518,7 @@ const posterConfig = computed(() => { ...@@ -480,7 +518,7 @@ const posterConfig = computed(() => {
480 lineNum: 2, 518 lineNum: 2,
481 width: 352, // 按比例调整 (440 * 0.8 = 352) 519 width: 352, // 按比例调整 (440 * 0.8 = 352)
482 textAlign: 'left', 520 textAlign: 'left',
483 - zIndex: 1 521 + zIndex: 1,
484 }, 522 },
485 ], 523 ],
486 blocks: [ 524 blocks: [
...@@ -491,7 +529,7 @@ const posterConfig = computed(() => { ...@@ -491,7 +529,7 @@ const posterConfig = computed(() => {
491 width: 600, // 按比例调整 (750 * 0.8 = 600) 529 width: 600, // 按比例调整 (750 * 0.8 = 600)
492 height: 427, // 按比例调整 (534 * 0.8 = 427) 530 height: 427, // 按比例调整 (534 * 0.8 = 427)
493 backgroundColor: '#ffffff', 531 backgroundColor: '#ffffff',
494 - zIndex: 0 532 + zIndex: 0,
495 }, 533 },
496 // 用户信息背景遮罩 534 // 用户信息背景遮罩
497 // { 535 // {
...@@ -503,7 +541,7 @@ const posterConfig = computed(() => { ...@@ -503,7 +541,7 @@ const posterConfig = computed(() => {
503 // borderRadius: 8, // 按比例调整 (10 * 0.8 = 8) 541 // borderRadius: 8, // 按比例调整 (10 * 0.8 = 8)
504 // zIndex: 1 542 // zIndex: 1
505 // } 543 // }
506 - ] 544 + ],
507 } 545 }
508 }) 546 })
509 547
...@@ -540,26 +578,30 @@ onMounted(async () => { ...@@ -540,26 +578,30 @@ onMounted(async () => {
540 /** 578 /**
541 * 监听背景图变化,重新生成海报 579 * 监听背景图变化,重新生成海报
542 */ 580 */
543 -watch(backgroundImages, (newVal, oldVal) => { 581 +watch(
544 - // 只有当前海报的背景图发生变化时才重新生成 582 + backgroundImages,
545 - const currentIndex = currentPosterIndex.value 583 + (newVal, oldVal) => {
546 - const newBgImage = newVal[currentIndex] 584 + // 只有当前海报的背景图发生变化时才重新生成
547 - const oldBgImage = oldVal?.[currentIndex] 585 + const currentIndex = currentPosterIndex.value
586 + const newBgImage = newVal[currentIndex]
587 + const oldBgImage = oldVal?.[currentIndex]
548 588
549 - if (newBgImage !== oldBgImage) { 589 + if (newBgImage !== oldBgImage) {
550 - console.log('背景图发生变化:', { currentIndex, newBgImage, oldBgImage }) 590 + console.log('背景图发生变化:', { currentIndex, newBgImage, oldBgImage })
551 591
552 - // 标记当前海报需要重新生成 592 + // 标记当前海报需要重新生成
553 - posterGeneratedFlags.value[currentIndex] = false 593 + posterGeneratedFlags.value[currentIndex] = false
554 - delete posterConfigHashes.value[currentIndex] 594 + delete posterConfigHashes.value[currentIndex]
555 595
556 - // 清除当前海报路径 596 + // 清除当前海报路径
557 - posterPath.value = '' 597 + posterPath.value = ''
558 598
559 - // 重新生成海报 599 + // 重新生成海报
560 - generateCurrentPoster() 600 + generateCurrentPoster()
561 - } 601 + }
562 -}, { deep: true }) 602 + },
603 + { deep: true }
604 +)
563 605
564 /** 606 /**
565 * 监听当前海报索引变化,切换海报 607 * 监听当前海报索引变化,切换海报
...@@ -574,17 +616,17 @@ watch(currentPosterIndex, (newIndex, oldIndex) => { ...@@ -574,17 +616,17 @@ watch(currentPosterIndex, (newIndex, oldIndex) => {
574 /** 616 /**
575 * 生成当前海报配置的哈希值 617 * 生成当前海报配置的哈希值
576 */ 618 */
577 -const generateConfigHash = (config) => { 619 +const generateConfigHash = config => {
578 const configStr = JSON.stringify({ 620 const configStr = JSON.stringify({
579 backgroundImage: backgroundImages.value[currentPosterIndex.value], 621 backgroundImage: backgroundImages.value[currentPosterIndex.value],
580 posterIndex: currentPosterIndex.value, 622 posterIndex: currentPosterIndex.value,
581 - mockData: currentMockData.value 623 + mockData: currentMockData.value,
582 }) 624 })
583 // 简单哈希函数 625 // 简单哈希函数
584 let hash = 0 626 let hash = 0
585 for (let i = 0; i < configStr.length; i++) { 627 for (let i = 0; i < configStr.length; i++) {
586 const char = configStr.charCodeAt(i) 628 const char = configStr.charCodeAt(i)
587 - hash = ((hash << 5) - hash) + char 629 + hash = (hash << 5) - hash + char
588 hash = hash & hash // 转换为32位整数 630 hash = hash & hash // 转换为32位整数
589 } 631 }
590 return hash.toString() 632 return hash.toString()
...@@ -606,7 +648,7 @@ const generateCurrentPosterIfNeeded = () => { ...@@ -606,7 +648,7 @@ const generateCurrentPosterIfNeeded = () => {
606 hasCustomBackground, 648 hasCustomBackground,
607 currentHash, 649 currentHash,
608 lastHash, 650 lastHash,
609 - hashChanged: lastHash !== currentHash 651 + hashChanged: lastHash !== currentHash,
610 }) 652 })
611 653
612 // 如果海报未生成过,或者配置发生了变化,则需要重新生成 654 // 如果海报未生成过,或者配置发生了变化,则需要重新生成
...@@ -668,39 +710,39 @@ const chooseBackgroundImage = () => { ...@@ -668,39 +710,39 @@ const chooseBackgroundImage = () => {
668 count: 1, 710 count: 1,
669 sizeType: ['compressed'], 711 sizeType: ['compressed'],
670 sourceType: ['album', 'camera'], 712 sourceType: ['album', 'camera'],
671 - success: (res) => { 713 + success: res => {
672 const tempFile = res.tempFiles[0] 714 const tempFile = res.tempFiles[0]
673 if (tempFile.size > 5 * 1024 * 1024) { 715 if (tempFile.size > 5 * 1024 * 1024) {
674 Taro.showToast({ 716 Taro.showToast({
675 title: '图片大小不能超过5MB', 717 title: '图片大小不能超过5MB',
676 - icon: 'none' 718 + icon: 'none',
677 }) 719 })
678 return 720 return
679 } 721 }
680 722
681 uploadBackgroundImage(tempFile.path) 723 uploadBackgroundImage(tempFile.path)
682 }, 724 },
683 - fail: (error) => { 725 + fail: error => {
684 console.error('选择图片失败:', error) 726 console.error('选择图片失败:', error)
685 // Taro.showToast({ 727 // Taro.showToast({
686 // title: '选择图片失败,请重试', 728 // title: '选择图片失败,请重试',
687 // icon: 'none' 729 // icon: 'none'
688 // }) 730 // })
689 - } 731 + },
690 }) 732 })
691 } 733 }
692 734
693 /** 735 /**
694 * 上传背景图片 736 * 上传背景图片
695 */ 737 */
696 -const uploadBackgroundImage = (filePath) => { 738 +const uploadBackgroundImage = filePath => {
697 Taro.showLoading({ title: '上传中...' }) 739 Taro.showLoading({ title: '上传中...' })
698 740
699 Taro.uploadFile({ 741 Taro.uploadFile({
700 url: BASE_URL + '/admin/?m=srv&a=upload', 742 url: BASE_URL + '/admin/?m=srv&a=upload',
701 filePath, 743 filePath,
702 name: 'file', 744 name: 'file',
703 - success: async (uploadRes) => { 745 + success: async uploadRes => {
704 const data = JSON.parse(uploadRes.data) 746 const data = JSON.parse(uploadRes.data)
705 if (data.code === 0 && data.data) { 747 if (data.code === 0 && data.data) {
706 const currentIndex = currentPosterIndex.value 748 const currentIndex = currentPosterIndex.value
...@@ -713,7 +755,7 @@ const uploadBackgroundImage = (filePath) => { ...@@ -713,7 +755,7 @@ const uploadBackgroundImage = (filePath) => {
713 try { 755 try {
714 const saveResult = await savePosterBackgroundAPI({ 756 const saveResult = await savePosterBackgroundAPI({
715 detail_id: currentPosterData.checkPointId, 757 detail_id: currentPosterData.checkPointId,
716 - poster_background_url: data.data.src 758 + poster_background_url: data.data.src,
717 }) 759 })
718 760
719 if (saveResult.code === 1) { 761 if (saveResult.code === 1) {
...@@ -744,18 +786,18 @@ const uploadBackgroundImage = (filePath) => { ...@@ -744,18 +786,18 @@ const uploadBackgroundImage = (filePath) => {
744 Taro.showToast({ title: data.msg || '上传失败', icon: 'none' }) 786 Taro.showToast({ title: data.msg || '上传失败', icon: 'none' })
745 } 787 }
746 }, 788 },
747 - fail: (error) => { 789 + fail: error => {
748 console.error('上传文件失败:', error) 790 console.error('上传文件失败:', error)
749 Taro.hideLoading() 791 Taro.hideLoading()
750 Taro.showToast({ title: '上传失败,请稍后重试', icon: 'none' }) 792 Taro.showToast({ title: '上传失败,请稍后重试', icon: 'none' })
751 - } 793 + },
752 }) 794 })
753 } 795 }
754 796
755 /** 797 /**
756 * 海报生成成功 798 * 海报生成成功
757 */ 799 */
758 -const onPosterSuccess = (result) => { 800 +const onPosterSuccess = result => {
759 const currentIndex = currentPosterIndex.value 801 const currentIndex = currentPosterIndex.value
760 posterPath.value = result.tempFilePath 802 posterPath.value = result.tempFilePath
761 posterGenerateFailed.value = false 803 posterGenerateFailed.value = false
...@@ -774,7 +816,7 @@ const onPosterSuccess = (result) => { ...@@ -774,7 +816,7 @@ const onPosterSuccess = (result) => {
774 console.log('海报生成成功:', { 816 console.log('海报生成成功:', {
775 currentIndex, 817 currentIndex,
776 posterPath: result.tempFilePath, 818 posterPath: result.tempFilePath,
777 - hasCustomBackground: !!backgroundImages.value[currentIndex] 819 + hasCustomBackground: !!backgroundImages.value[currentIndex],
778 }) 820 })
779 821
780 Taro.showToast({ title: '海报生成成功', icon: 'success' }) 822 Taro.showToast({ title: '海报生成成功', icon: 'success' })
...@@ -783,7 +825,7 @@ const onPosterSuccess = (result) => { ...@@ -783,7 +825,7 @@ const onPosterSuccess = (result) => {
783 /** 825 /**
784 * 海报生成失败 826 * 海报生成失败
785 */ 827 */
786 -const onPosterFail = (error) => { 828 +const onPosterFail = error => {
787 const currentIndex = currentPosterIndex.value 829 const currentIndex = currentPosterIndex.value
788 shouldGeneratePoster.value = false 830 shouldGeneratePoster.value = false
789 posterGenerateFailed.value = true 831 posterGenerateFailed.value = true
...@@ -843,7 +885,7 @@ const savePoster = () => { ...@@ -843,7 +885,7 @@ const savePoster = () => {
843 success: () => { 885 success: () => {
844 Taro.showToast({ title: '保存成功', icon: 'success' }) 886 Taro.showToast({ title: '保存成功', icon: 'success' })
845 }, 887 },
846 - fail: (err) => { 888 + fail: err => {
847 if (err.errMsg.includes('auth deny')) { 889 if (err.errMsg.includes('auth deny')) {
848 Taro.showModal({ 890 Taro.showModal({
849 title: '提示', 891 title: '提示',
...@@ -852,12 +894,12 @@ const savePoster = () => { ...@@ -852,12 +894,12 @@ const savePoster = () => {
852 confirmText: '去设置', 894 confirmText: '去设置',
853 success: () => { 895 success: () => {
854 Taro.openSetting() 896 Taro.openSetting()
855 - } 897 + },
856 }) 898 })
857 } else { 899 } else {
858 Taro.showToast({ title: '保存失败', icon: 'none' }) 900 Taro.showToast({ title: '保存失败', icon: 'none' })
859 } 901 }
860 - } 902 + },
861 }) 903 })
862 } 904 }
863 905
...@@ -870,18 +912,16 @@ const showNoActivityConfirm = () => { ...@@ -870,18 +912,16 @@ const showNoActivityConfirm = () => {
870 content: '您还没有参加过活动,请先参加活动后再来生成海报', 912 content: '您还没有参加过活动,请先参加活动后再来生成海报',
871 showCancel: false, 913 showCancel: false,
872 confirmText: '知道了', 914 confirmText: '知道了',
873 - success: (res) => { 915 + success: res => {
874 if (res.confirm) { 916 if (res.confirm) {
875 // 返回上一页 917 // 返回上一页
876 Taro.navigateBack({ 918 Taro.navigateBack({
877 - delta: 1 919 + delta: 1,
878 }) 920 })
879 } 921 }
880 - } 922 + },
881 }) 923 })
882 } 924 }
883 -
884 -
885 </script> 925 </script>
886 926
887 <style scoped> 927 <style scoped>
......