fix(购物车): 修复表单URL处理逻辑并添加购物车数据过期检查
修复课程详情页中表单URL的空值检查问题 为购物车数据添加时间戳和过期检查逻辑 优化结账页面个人信息录入的条件渲染
Showing
3 changed files
with
81 additions
and
36 deletions
| ... | @@ -21,7 +21,32 @@ export function provideCart(mode = CartMode.MULTIPLE) { | ... | @@ -21,7 +21,32 @@ export function provideCart(mode = CartMode.MULTIPLE) { |
| 21 | try { | 21 | try { |
| 22 | const storedCart = localStorage.getItem('cart') | 22 | const storedCart = localStorage.getItem('cart') |
| 23 | if (storedCart) { | 23 | if (storedCart) { |
| 24 | - cartItems.value = JSON.parse(storedCart) | 24 | + const cartData = JSON.parse(storedCart) |
| 25 | + | ||
| 26 | + // 检查是否为新格式(包含时间戳) | ||
| 27 | + if (cartData && typeof cartData === 'object' && cartData.timestamp) { | ||
| 28 | + const currentTime = Date.now() | ||
| 29 | + const oneDay = 24 * 60 * 60 * 1000 // 一天的毫秒数 | ||
| 30 | + | ||
| 31 | + // 检查缓存是否过期(超过一天) | ||
| 32 | + if (currentTime - cartData.timestamp > oneDay) { | ||
| 33 | + // 购物车缓存已过期,清空购物车 | ||
| 34 | + localStorage.removeItem('cart') | ||
| 35 | + cartItems.value = [] | ||
| 36 | + } else { | ||
| 37 | + // 缓存未过期,加载购物车数据 | ||
| 38 | + cartItems.value = cartData.items || [] | ||
| 39 | + } | ||
| 40 | + } else { | ||
| 41 | + // 兼容旧格式(直接是数组) | ||
| 42 | + if (Array.isArray(cartData)) { | ||
| 43 | + cartItems.value = cartData | ||
| 44 | + } else { | ||
| 45 | + // 格式不正确,清空缓存 | ||
| 46 | + localStorage.removeItem('cart') | ||
| 47 | + cartItems.value = [] | ||
| 48 | + } | ||
| 49 | + } | ||
| 25 | } | 50 | } |
| 26 | } catch (error) { | 51 | } catch (error) { |
| 27 | console.error('Failed to parse cart from localStorage:', error) | 52 | console.error('Failed to parse cart from localStorage:', error) |
| ... | @@ -30,7 +55,11 @@ export function provideCart(mode = CartMode.MULTIPLE) { | ... | @@ -30,7 +55,11 @@ export function provideCart(mode = CartMode.MULTIPLE) { |
| 30 | 55 | ||
| 31 | // 监听购物车变化并保存到localStorage | 56 | // 监听购物车变化并保存到localStorage |
| 32 | watchEffect(() => { | 57 | watchEffect(() => { |
| 33 | - localStorage.setItem('cart', JSON.stringify(cartItems.value)) | 58 | + const cartData = { |
| 59 | + items: cartItems.value, | ||
| 60 | + timestamp: Date.now() // 添加时间戳 | ||
| 61 | + } | ||
| 62 | + localStorage.setItem('cart', JSON.stringify(cartData)) | ||
| 34 | }) | 63 | }) |
| 35 | 64 | ||
| 36 | // 添加商品到购物车 | 65 | // 添加商品到购物车 | ... | ... |
| ... | @@ -79,7 +79,7 @@ | ... | @@ -79,7 +79,7 @@ |
| 79 | <!-- Checkout Form --> | 79 | <!-- Checkout Form --> |
| 80 | <div class="px-4 pt-4"> | 80 | <div class="px-4 pt-4"> |
| 81 | <form @submit.prevent="handleSubmit"> | 81 | <form @submit.prevent="handleSubmit"> |
| 82 | - <FrostedGlass class="rounded-xl p-4 mb-4"> | 82 | + <FrostedGlass v-if="shouldShowInfoEntry" class="rounded-xl p-4 mb-4"> |
| 83 | <!-- 预览个人信息iframe --> | 83 | <!-- 预览个人信息iframe --> |
| 84 | <iframe | 84 | <iframe |
| 85 | v-if="!showInfoEntry" | 85 | v-if="!showInfoEntry" |
| ... | @@ -288,41 +288,45 @@ onMounted(async () => { | ... | @@ -288,41 +288,45 @@ onMounted(async () => { |
| 288 | if (cartItems.value && cartItems.value.length > 0) { | 288 | if (cartItems.value && cartItems.value.length > 0) { |
| 289 | const itemWithForm = cartItems.value.find(item => item.form_url) | 289 | const itemWithForm = cartItems.value.find(item => item.form_url) |
| 290 | 290 | ||
| 291 | - if (itemWithForm && itemWithForm.form_url) { | 291 | + // 如果没有找到包含form_url的项目,或者form_url为空,则跳过个人信息录入 |
| 292 | - // 检查用户是否已经录入过个人信息 | 292 | + if (!itemWithForm || !itemWithForm.form_url) { |
| 293 | - const infoEntryKey = `info_entry_completed_${itemWithForm.id}` | 293 | + console.log('未找到form_url或form_url为空,跳过个人信息录入') |
| 294 | - currentInfoEntryKey = infoEntryKey // 保存键名用于清理 | 294 | + return |
| 295 | - const savedInfoData = localStorage.getItem(infoEntryKey) | 295 | + } |
| 296 | - | ||
| 297 | - console.log('检查个人信息录入状态:', { | ||
| 298 | - courseId: itemWithForm.id, | ||
| 299 | - hasSavedData: !!savedInfoData | ||
| 300 | - }) | ||
| 301 | 296 | ||
| 302 | - if (!savedInfoData) { | 297 | + // 检查用户是否已经录入过个人信息 |
| 303 | - // 只有未录入过信息时才弹出弹窗 | 298 | + const infoEntryKey = `info_entry_completed_${itemWithForm.id}` |
| 299 | + currentInfoEntryKey = infoEntryKey // 保存键名用于清理 | ||
| 300 | + const savedInfoData = localStorage.getItem(infoEntryKey) | ||
| 301 | + | ||
| 302 | + console.log('检查个人信息录入状态:', { | ||
| 303 | + courseId: itemWithForm.id, | ||
| 304 | + hasSavedData: !!savedInfoData | ||
| 305 | + }) | ||
| 306 | + | ||
| 307 | + if (!savedInfoData) { | ||
| 308 | + // 只有未录入过信息时才弹出弹窗 | ||
| 309 | + showInfoEntry.value = true | ||
| 310 | + // 设置弹窗标题 | ||
| 311 | + iframeTitle.value = '个人信息录入' | ||
| 312 | + iframeSrc.value = itemWithForm.form_url | ||
| 313 | + iframeType.value = 'add' | ||
| 314 | + console.log('首次录入,显示个人信息录入弹窗') | ||
| 315 | + } else { | ||
| 316 | + // 已录入过信息,从缓存中恢复数据并显示预览 | ||
| 317 | + try { | ||
| 318 | + const infoData = JSON.parse(savedInfoData) | ||
| 319 | + formData.value.customize_id = infoData.customize_id | ||
| 320 | + iframeInfoSrc.value = infoData.form_url + '&page_type=info' + '&data_id=' + infoData.customize_id | ||
| 321 | + console.log('从缓存恢复个人信息数据:', infoData) | ||
| 322 | + | ||
| 323 | + // 不再需要动态调整iframe高度 | ||
| 324 | + } catch (error) { | ||
| 325 | + console.error('解析缓存数据失败:', error) | ||
| 326 | + // 如果解析失败,重新录入 | ||
| 304 | showInfoEntry.value = true | 327 | showInfoEntry.value = true |
| 305 | - // 设置弹窗标题 | ||
| 306 | - iframeTitle.value = '个人信息录入' | ||
| 307 | iframeSrc.value = itemWithForm.form_url | 328 | iframeSrc.value = itemWithForm.form_url |
| 308 | iframeType.value = 'add' | 329 | iframeType.value = 'add' |
| 309 | - console.log('首次录入,显示个人信息录入弹窗') | ||
| 310 | - } else { | ||
| 311 | - // 已录入过信息,从缓存中恢复数据并显示预览 | ||
| 312 | - try { | ||
| 313 | - const infoData = JSON.parse(savedInfoData) | ||
| 314 | - formData.value.customize_id = infoData.customize_id | ||
| 315 | - iframeInfoSrc.value = infoData.form_url + '&page_type=info' + '&data_id=' + infoData.customize_id | ||
| 316 | - console.log('从缓存恢复个人信息数据:', infoData) | ||
| 317 | - | ||
| 318 | - // 不再需要动态调整iframe高度 | ||
| 319 | - } catch (error) { | ||
| 320 | - console.error('解析缓存数据失败:', error) | ||
| 321 | - // 如果解析失败,重新录入 | ||
| 322 | - showInfoEntry.value = true | ||
| 323 | - iframeSrc.value = itemWithForm.form_url | ||
| 324 | - iframeType.value = 'add' | ||
| 325 | - } | ||
| 326 | } | 330 | } |
| 327 | } | 331 | } |
| 328 | } | 332 | } |
| ... | @@ -357,6 +361,15 @@ const iframeInfoSrc = ref(null) | ... | @@ -357,6 +361,15 @@ const iframeInfoSrc = ref(null) |
| 357 | const infoEntryIframe = ref(null) | 361 | const infoEntryIframe = ref(null) |
| 358 | 362 | ||
| 359 | /** | 363 | /** |
| 364 | + * 检查是否需要显示个人信息录入UI | ||
| 365 | + */ | ||
| 366 | +const shouldShowInfoEntry = computed(() => { | ||
| 367 | + if (!cartItems.value || cartItems.value.length === 0) return false | ||
| 368 | + const itemWithForm = cartItems.value.find(item => item.form_url) | ||
| 369 | + return itemWithForm && itemWithForm.form_url | ||
| 370 | +}) | ||
| 371 | + | ||
| 372 | +/** | ||
| 360 | * 监听个人信息录入弹窗状态,动态修改页面标题 | 373 | * 监听个人信息录入弹窗状态,动态修改页面标题 |
| 361 | */ | 374 | */ |
| 362 | watch(showInfoEntry, (newVal) => { | 375 | watch(showInfoEntry, (newVal) => { | ... | ... |
| ... | @@ -466,8 +466,11 @@ const handlePurchase = () => { | ... | @@ -466,8 +466,11 @@ const handlePurchase = () => { |
| 466 | price: course.value.price, | 466 | price: course.value.price, |
| 467 | imageUrl: course.value.imageUrl, | 467 | imageUrl: course.value.imageUrl, |
| 468 | form: course.value.form, // 报名关联的表单 | 468 | form: course.value.form, // 报名关联的表单 |
| 469 | - // 需要把当前页面域名拼写进去 | 469 | + } |
| 470 | - form_url: window.location.origin + course.value.form_url, // 课程关联的表单的 URL | 470 | + |
| 471 | + // 只有当form_url存在且不为空时才添加该字段 | ||
| 472 | + if (course.value.form_url && course.value.form_url.trim() !== '') { | ||
| 473 | + cartItem.form_url = window.location.origin + course.value.form_url // 课程关联的表单的 URL | ||
| 471 | } | 474 | } |
| 472 | 475 | ||
| 473 | // 调试日志:检查传递给addToCart的数据 | 476 | // 调试日志:检查传递给addToCart的数据 | ... | ... |
-
Please register or login to post a comment