feat(recall): 新增分享海报功能组件和页面
添加 RecallPoster 组件用于生成分享海报 创建 PosterPage 页面路由和视图 实现海报背景更换、竖排文字绘制和二维码展示功能
Showing
4 changed files
with
73 additions
and
1 deletions
| ... | @@ -32,6 +32,7 @@ declare module 'vue' { | ... | @@ -32,6 +32,7 @@ declare module 'vue' { |
| 32 | PdfPreview: typeof import('./components/ui/PdfPreview.vue')['default'] | 32 | PdfPreview: typeof import('./components/ui/PdfPreview.vue')['default'] |
| 33 | PdfViewer: typeof import('./components/ui/PdfViewer.vue')['default'] | 33 | PdfViewer: typeof import('./components/ui/PdfViewer.vue')['default'] |
| 34 | PostCountModel: typeof import('./components/count/postCountModel.vue')['default'] | 34 | PostCountModel: typeof import('./components/count/postCountModel.vue')['default'] |
| 35 | + RecallPoster: typeof import('./components/ui/RecallPoster.vue')['default'] | ||
| 35 | ReviewPopup: typeof import('./components/courses/ReviewPopup.vue')['default'] | 36 | ReviewPopup: typeof import('./components/courses/ReviewPopup.vue')['default'] |
| 36 | RouterLink: typeof import('vue-router')['RouterLink'] | 37 | RouterLink: typeof import('vue-router')['RouterLink'] |
| 37 | RouterView: typeof import('vue-router')['RouterView'] | 38 | RouterView: typeof import('vue-router')['RouterView'] | ... | ... |
src/components/ui/RecallPoster.vue
0 → 100644
This diff is collapsed. Click to expand it.
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-03-20 20:36:36 | 2 | * @Date: 2025-03-20 20:36:36 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-12-23 15:31:50 | 4 | + * @LastEditTime: 2025-12-23 15:51:28 |
| 5 | * @FilePath: /mlaj/src/router/routes.js | 5 | * @FilePath: /mlaj/src/router/routes.js |
| 6 | * @Description: 路由地址映射配置 | 6 | * @Description: 路由地址映射配置 |
| 7 | */ | 7 | */ |
| ... | @@ -139,6 +139,12 @@ export const routes = [ | ... | @@ -139,6 +139,12 @@ export const routes = [ |
| 139 | meta: { title: '活动历史' }, | 139 | meta: { title: '活动历史' }, |
| 140 | }, | 140 | }, |
| 141 | { | 141 | { |
| 142 | + path: '/recall/poster', | ||
| 143 | + name: 'Poster', | ||
| 144 | + component: () => import('../views/recall/PosterPage.vue'), | ||
| 145 | + meta: { title: '分享海报' }, | ||
| 146 | + }, | ||
| 147 | + { | ||
| 142 | path: '/checkout', | 148 | path: '/checkout', |
| 143 | name: 'CheckoutPage', | 149 | name: 'CheckoutPage', |
| 144 | component: () => import('../views/checkout/CheckoutPage.vue'), | 150 | component: () => import('../views/checkout/CheckoutPage.vue'), | ... | ... |
src/views/recall/PosterPage.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2025-12-23 15:50:59 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2025-12-23 16:40:19 | ||
| 5 | + * @FilePath: /mlaj/src/views/recall/PosterPage.vue | ||
| 6 | + * @Description: 分享海报页面 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <div class="min-h-screen bg-[#1E40C8] relative flex flex-col"> | ||
| 10 | + | ||
| 11 | + <!-- Poster Container (Scrollable Area) --> | ||
| 12 | + <div class="flex-1 overflow-y-auto px-6 pt-6 pb-32 flex flex-col items-center"> | ||
| 13 | + <RecallPoster | ||
| 14 | + :bg-url="posterBg" | ||
| 15 | + :title="title" | ||
| 16 | + :logo-url="logoUrl" | ||
| 17 | + :qr-url="qrCodeUrl" | ||
| 18 | + /> | ||
| 19 | + </div> | ||
| 20 | + | ||
| 21 | + <!-- Buttons (Fixed at Bottom) --> | ||
| 22 | + <div class="fixed bottom-0 left-0 right-0 bg-[#1E40C8] px-8 py-6 pb-10 flex gap-4 z-50 max-w-md mx-auto w-full"> | ||
| 23 | + <van-uploader :after-read="afterRead" accept="image/*" class="flex-1 w-full" :show-upload="false"> | ||
| 24 | + <template #default> | ||
| 25 | + <van-button block color="#0052D9" plain | ||
| 26 | + class="!rounded-lg !h-[44px] !text-[15px] !font-bold w-full !border-[#0052D9] !bg-white"> | ||
| 27 | + 更换图片 | ||
| 28 | + </van-button> | ||
| 29 | + </template> | ||
| 30 | + </van-uploader> | ||
| 31 | + </div> | ||
| 32 | + </div> | ||
| 33 | +</template> | ||
| 34 | + | ||
| 35 | +<script setup> | ||
| 36 | +import { ref } from 'vue' | ||
| 37 | +import { useRoute, useRouter } from 'vue-router' | ||
| 38 | +import { useTitle } from '@vueuse/core' | ||
| 39 | +import RecallPoster from '@/components/ui/RecallPoster.vue' | ||
| 40 | + | ||
| 41 | +const $route = useRoute(); | ||
| 42 | +const $router = useRouter(); | ||
| 43 | +useTitle('分享海报'); | ||
| 44 | + | ||
| 45 | +// Assets | ||
| 46 | +const defaultBg = 'https://cdn.ipadbiz.cn/mlaj/images/test-bgg03.jpg?imageMogr2/thumbnail/800x/strip/quality/80' | ||
| 47 | +const logoUrl = 'https://cdn.ipadbiz.cn/mlaj/recall/poster/kai@2x.png' | ||
| 48 | +const qrCodeUrl = 'https://cdn.ipadbiz.cn/mlaj/recall/poster/%E4%BA%8C%E7%BB%B4%E7%A0%81@2x.png' | ||
| 49 | + | ||
| 50 | +// State | ||
| 51 | +const posterBg = ref(defaultBg) | ||
| 52 | +const title = ref('2017.7.6-7.11 【自然的恩典】“爱我中华”优秀传统文化夏令营-天津场开启~') | ||
| 53 | + | ||
| 54 | +// Actions | ||
| 55 | +const afterRead = (file) => { | ||
| 56 | + // Use Object URL for local preview to avoid uploading | ||
| 57 | + posterBg.value = URL.createObjectURL(file.file) | ||
| 58 | +} | ||
| 59 | +</script> | ||
| 60 | + | ||
| 61 | +<style lang="less" scoped> | ||
| 62 | +:deep(.van-uploader__input-wrapper) { | ||
| 63 | + width: 100%; | ||
| 64 | +} | ||
| 65 | +</style> |
-
Please register or login to post a comment