hookehuyr

feat(recall): 添加活动历史页面及路由配置

- 新增活动历史页面组件 ActivityHistoryPage.vue
- 在路由配置中添加活动历史页面路径
- 添加活动历史页面所需的背景图片资源
/*
* @Date: 2025-03-20 20:36:36
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-12-23 14:27:58
* @LastEditTime: 2025-12-23 15:31:50
* @FilePath: /mlaj/src/router/routes.js
* @Description: 路由地址映射配置
*/
......@@ -132,7 +132,12 @@ export const routes = [
component: () => import('../views/recall/timeline.vue'),
meta: { title: '时光机旅程' },
},
{
path: '/recall/activity-history',
name: 'ActivityHistory',
component: () => import('../views/recall/ActivityHistoryPage.vue'),
meta: { title: '活动历史' },
},
{
path: '/checkout',
name: 'CheckoutPage',
......
<template>
<div class="activity-history-page w-full min-h-screen bg-[#F7F8FA] relative pb-[140px]">
<!-- Header Banner -->
<div class="w-full relative h-[180px] overflow-hidden">
<img :src="historyBg" class="w-full h-full object-cover" alt="History Banner" />
<div class="absolute inset-0 flex flex-col justify-center items-center text-center px-4">
<h1 class="text-[#FFDD01] text-3xl font-bold mb-2 tracking-wider drop-shadow-md mt-3">2020-2025</h1>
<h2 class="text-white text-2xl font-bold mb-4 tracking-wider drop-shadow-md">您的活动历史</h2>
<div class="w-full max-w-md rounded-lg px-4 py-2"
style="background: linear-gradient(96deg, rgba(82,88,254,0) 0%, #5258FE 47%, rgba(92,106,241,0) 100%);">
<p class="text-white text-xs leading-tight opacity-90">
查看并确认您参与的星球活动记录,<br>
如果有缺失,点击没找到我的星球活动,进行补充
</p>
</div>
</div>
</div>
<!-- Filter Bar -->
<div class="bg-white px-4 py-3 flex justify-between items-center sticky top-0 z-20 shadow-sm">
<span class="text-[#333] font-medium text-sm">活动记录</span>
<div class="flex items-center text-[#666] text-sm">
<span>{{ activities.length }}条</span>
</div>
</div>
<!-- List -->
<div class="px-4 py-4 space-y-4">
<div v-for="item in activities" :key="item.id" class="bg-white rounded-xl py-4 pr-4 pl-0 shadow-sm relative overflow-hidden flex">
<!-- Blue Marker (Absolute or Flex) -->
<!-- Based on image, it is sticking to the left edge but inside the card padding area potentially, or flush left -->
<!-- Looking at image, it is flush left to the card container -->
<div class="w-1 h-4 bg-[#0052D9] rounded-r-sm mt-1 shrink-0 self-start"></div>
<div class="pl-3 flex-1">
<h3 class="text-[#333] font-bold text-base leading-snug">
{{ item.title }}
</h3>
<div class="border-t border-dashed border-gray-200 my-3"></div>
<div class="flex justify-between items-center text-xs text-[#666] mb-2">
<span>单价: ¥{{ item.price.toFixed(2) }}/人</span>
<span>人数: {{ item.count }}</span>
</div>
<div class="flex justify-between items-center text-xs text-[#666] mb-4">
<span>下单时间: {{ item.date }}</span>
<span class="text-[#FF3B30] font-bold">实付金额: ¥{{ item.total.toFixed(0) }}</span>
</div>
<div class="flex justify-end">
<van-button size="small" plain color="#0052D9" class="!rounded-full !px-4 !h-[28px] !text-xs"
@click="handleGeneratePoster(item)">
生成活动海报
</van-button>
</div>
</div>
</div>
</div>
<!-- Fixed Bottom Buttons -->
<div
class="fixed bottom-0 left-0 right-0 bg-white/60 backdrop-blur-md p-4 pb-8 z-30 shadow-[0_-2px_10px_rgba(0,0,0,0.05)]">
<van-button block color="#0052D9" class="!rounded-lg !mb-3 !h-[44px] !text-base !font-bold"
@click="handleCollectCoins">
收集星球币
</van-button>
<van-button block plain color="#0052D9" class="!rounded-lg !h-[44px] !text-base !font-medium"
@click="showMissingPopup = true">
<template #icon>
<van-icon name="question-o" class="mr-1" />
</template>
没找到我的星球活动
</van-button>
</div>
<!-- Missing Activity Popup -->
<van-popup v-model:show="showMissingPopup" round position="bottom" :style="{ height: '60%' }" class="flex flex-col">
<div class="p-4 flex-1 flex flex-col">
<h3 class="text-center font-bold text-lg mb-6 text-[#333]">补充活动信息</h3>
<div class="flex-1 bg-[#F7F8FA] rounded-lg p-3 mb-6">
<textarea v-model="missingInfo"
class="w-full h-full bg-transparent border-none outline-none resize-none text-sm text-[#333] placeholder:text-[#999]"
placeholder="请把缺失的星球活动,补充在这里,留下活动的名称、时间、地点、参加人数等信息"></textarea>
</div>
<van-button block color="#0052D9" class="!rounded-lg !h-[44px] !text-base !font-bold"
@click="handleSubmitMissing">
提交
</van-button>
</div>
</van-popup>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useTitle } from '@vueuse/core'
import { showToast } from 'vant'
// Assets
import historyBg from '@/assets/images/recall/history_bg@2x.png'
const router = useRouter()
useTitle('活动历史')
// Mock Data
const activities = ref([
{
id: 1,
title: '2025.11月3日-10日江苏东台养生营,邀您一起进入童话世界!',
price: 3200.00,
count: 2,
date: '2025-11-03',
total: 6400
},
{
id: 2,
title: '【自然的恩典】青少年成长营-贵阳百花湖3(小学初中专场)',
price: 3999.00,
count: 2,
date: '2025-10-03',
total: 7998
},
{
id: 3,
title: '2024年4月22-25日浙江义乌【中华智慧商业应用论坛】',
price: 3200.00,
count: 1,
date: '2024-04-03',
total: 3200
},
{
id: 4,
title: '2023.7.6-7.11【自然的恩典】“爱我中华”优秀传统文化夏令营-天津场',
price: 3990.00,
count: 1,
date: '2023-07-01',
total: 3990
}
])
// State
const showMissingPopup = ref(false)
const missingInfo = ref('')
// Actions
const handleGeneratePoster = (item) => {
showToast('生成海报: ' + item.title)
}
const handleCollectCoins = () => {
showToast('收集星球币成功')
// Navigate to coins page or show animation
}
const handleSubmitMissing = () => {
if (!missingInfo.value.trim()) {
showToast('请输入活动信息')
return
}
// TODO: Submit to API
showToast({
message: '感谢您为我们找回偏轨的星球活动',
icon: 'success'
})
showMissingPopup.value = false
missingInfo.value = ''
}
</script>
<style lang="less" scoped>
// Custom Scrollbar hide for cleaner look if needed
::-webkit-scrollbar {
width: 0px;
background: transparent;
}
</style>