海报update
This commit is contained in:
parent
ac431927b7
commit
7c1fdb0647
@ -118,7 +118,7 @@ router.beforeEach((to, from, next) => {
|
||||
if (!IS_PROD) {
|
||||
localStorage.setItem(
|
||||
'saas_token',
|
||||
'eyJpdiI6ImNoV0hTOFJCSjlSMklkYis4OHUrblE9PSIsInZhbHVlIjoicGZCZjFjS3d1UUl0ek1sUW52aVdqcGo2V0VwZGE4SCtpZTUrS1lGQ0czcDJLcDB2YlpENlNZd28xNkl1ZGJCTiIsIm1hYyI6IjhkYzlkMzAzZGQ2YTljMTVlY2YwOWIxMmQ2Y2I0ODE2M2Y5MDExNDdjMWMxZWU0ZDYyNWNmNmFkYTlhMmMzNTEifQ=='
|
||||
'eyJpdiI6IlAzSFM4cHFJT01RN3R3OUMxV0ptM3c9PSIsInZhbHVlIjoiNFl6QUhcL3daME9QOTZjTVMzTFpJeUtJZ01NZ3hBb0ZtYmlRSlk5ZkVmK2l3Q1NSUGhRNm5GYXE2ZHo4TUtTVDQiLCJtYWMiOiJjODdkY2ZjYjc2NjI4MjkwMDUyNmQ3OGNmNjc1YTc0MGY5ZjNiZjYyZjBmMGYxZWNkMzEwNzhhMjZlMWJlY2FhIn0='
|
||||
)
|
||||
localStorage.setItem('authorize_at', '2022-01-17 10:39:24')
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import { baseApi, baseApiV2 } from '@/config'
|
||||
import store from '@/store'
|
||||
import router from '@/router'
|
||||
const service = axios.create({
|
||||
baseURL: location.href.includes('https') ? '/api' : baseApiV2, // url = base api url + request url
|
||||
baseURL: location.href.includes('https') ? '/api' : 'https://love.ufutx.cn/api', // url = base api url + request url
|
||||
withCredentials: false, // send cookies when cross-domain requests
|
||||
timeout: 12000, // request timeout
|
||||
headers: {
|
||||
|
||||
@ -25,10 +25,17 @@
|
||||
<span class="confirm-btn" @click="showActivityPicker = false">确定</span>
|
||||
</div>
|
||||
<div class="scroll-wrapper">
|
||||
<van-list v-model:loading="listLoading" :finished="listFinished" finished-text="没有更多活动了"
|
||||
<van-list
|
||||
v-model:loading="listLoading"
|
||||
:finished="listFinished"
|
||||
finished-text="没有更多活动了"
|
||||
@load="onLoadMore">
|
||||
<div v-for="item in activityList" :key="item.id" class="activity-item"
|
||||
:class="{ active: selectedActivity?.id === item.id }" @click="onSelectActivity(item)">
|
||||
<div
|
||||
v-for="item in activityList"
|
||||
:key="item.id"
|
||||
class="activity-item"
|
||||
:class="{ active: selectedActivity?.id === item.id }"
|
||||
@click="onSelectActivity(item)">
|
||||
<div class="activity-title">{{ item.title }}</div>
|
||||
<div class="activity-time">{{ item.Subtitle }} | {{ formatDateToShow(item.end_time) }}</div>
|
||||
</div>
|
||||
@ -91,99 +98,118 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { nextTick, onMounted, ref, watch } from 'vue'
|
||||
<script>
|
||||
import { nextTick } from 'vue' // 注意:Vue 2 中通常不需要从 vue 导入 nextTick,直接使用 this.$nextTick
|
||||
import html2canvas from 'html2canvas'
|
||||
import { showDialog, showImagePreview, showLoadingToast, showToast } from 'vant'
|
||||
import requestApp from '@/utils/requestApp'
|
||||
import { ImagePreview, Icon, Loading } from 'vant'
|
||||
import { $toastText, $toastSuccess, $toastLoading, $toastClear } from '@/config/toast'
|
||||
import requestApp from '@/utils/request'
|
||||
import QRCode from 'qrcode'
|
||||
import { weXinShare } from '@/plugins/wxShare'
|
||||
import Vue from 'vue'
|
||||
|
||||
// 🔥 主办方:从活动接口自动获取,无需手动选择
|
||||
const sponsorName = ref('')
|
||||
Vue.use(Icon)
|
||||
Vue.use(Loading)
|
||||
|
||||
const posterRef = ref(null)
|
||||
const posterImg = ref('')
|
||||
const isGenerating = ref(false)
|
||||
const isWeChatEnv = ref(false)
|
||||
const qrcodeCanvas = ref(null)
|
||||
|
||||
const activityList = ref([])
|
||||
const selectedActivity = ref(null)
|
||||
const selectedActivityTitle = ref('')
|
||||
const showActivityPicker = ref(false)
|
||||
const listLoading = ref(false)
|
||||
const listFinished = ref(true)
|
||||
const openId = ref('')
|
||||
|
||||
// 监听选中的活动:自动填充主办方 + 生成二维码
|
||||
watch(selectedActivity, async (newVal) => {
|
||||
if (newVal && newVal.id && qrcodeCanvas.value) {
|
||||
// 自动从活动数据中读取主办方
|
||||
sponsorName.value = newVal.sponsor || ''
|
||||
openId.value = localStorage.getItem('openid')
|
||||
const link = `https://love.ufutx.cn/api/official/live/wechat/FamilyAuth?merchant_id=44&serve_tab=&from_openid=${openId.value}&url=https%3A%2F%2Flove.ufutx.cn%2Fpu%2F%23%2FactivityDetails%2F${newVal.id}`
|
||||
await QRCode.toCanvas(qrcodeCanvas.value, link, {
|
||||
width: 76,
|
||||
margin: 1,
|
||||
color: { dark: '#000000', light: '#ffffff' }
|
||||
})
|
||||
export default {
|
||||
name: 'ActivityPoster',
|
||||
data() {
|
||||
return {
|
||||
// 响应式数据 (原 ref 和 reactive)
|
||||
sponsorName: '',
|
||||
posterImg: '',
|
||||
isGenerating: false,
|
||||
isWeChatEnv: false,
|
||||
activityList: [],
|
||||
selectedActivity: null,
|
||||
selectedActivityTitle: '',
|
||||
showActivityPicker: false,
|
||||
listLoading: false,
|
||||
listFinished: true,
|
||||
openId: ''
|
||||
// 注意:qrcodeCanvas 作为 DOM 引用,通常在 mounted 中通过 this.$refs 访问
|
||||
}
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
// 替代 onMounted
|
||||
this.detectWeChatEnv()
|
||||
this.getData()
|
||||
console.log('33')
|
||||
},
|
||||
methods: {
|
||||
// 替代 script setup 中的函数
|
||||
async getData() {
|
||||
console.log('33455')
|
||||
const vm = this
|
||||
|
||||
const getData = () => {
|
||||
listLoading.value = true
|
||||
weXinShare('https://image.fulllinkai.com/202310/28/88e931a50ec0a8094fb46191b389457e.png', `https://health.ufutx.cn/go_html/role_apply#/activityPoster`, '活动海报生成「saas」', '查看详情')
|
||||
requestApp({ url: '/sh5/uftx/community/activity/list', method: 'get' })
|
||||
.then((res) => {
|
||||
if (res.code === 0 && Array.isArray(res.data)) {
|
||||
activityList.value = res.data
|
||||
// 默认选中第一个活动,自动填充主办方
|
||||
// if (res.data.length > 0) {
|
||||
// onSelectActivity(res.data[0]);
|
||||
this.listLoading = true
|
||||
// 注意:weXinShare 需要确保在 Vue 2 实例上下文中可用
|
||||
vm.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
// if (vm.$store.state.app.configData) {
|
||||
const urls = `${vm.$shareCallback}/api/official/live/wechat/FamilyAuth?from_openid=${localStorage.getItem('openid')}&merchant_id=${vm.$store.state.app.merchant_id}&spread_merchant_id=${vm.$store.state.app.spread_merchant_id}&url=` + encodeURIComponent(`${vm.$shareCallback}/pu/#/VIPDetail/${vm.id}`)
|
||||
vm.$shareList(
|
||||
'https://image.fulllinkai.com/202310/28/88e931a50ec0a8094fb46191b389457e.png?x-oss-process=image/resize,w_200,h_200',
|
||||
urls,
|
||||
'查看详情',
|
||||
'活动海报生成「saas」'
|
||||
)
|
||||
// }
|
||||
}, 300)
|
||||
})
|
||||
// vm.$shareList('https://image.fulllinkai.com/202310/28/88e931a50ec0a8094fb46191b389457e.png',
|
||||
// `https://health.ufutx.cn/go_html/role_apply#/activityPoster`,
|
||||
// '查看详情', '活动海报生成「saas」')
|
||||
|
||||
try {
|
||||
const res = await requestApp({
|
||||
url: '/s/h5/uftx/community/activity/list',
|
||||
method: 'get'
|
||||
})
|
||||
console.log(res, 'res---')
|
||||
|
||||
if (Array.isArray(res)) {
|
||||
this.activityList = res
|
||||
} else {
|
||||
showToast('活动列表获取失败')
|
||||
$toastText('活动列表获取失败')
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(this.activityList, ' this.activityList')
|
||||
} catch (err) {
|
||||
console.error('获取活动列表失败:', err)
|
||||
showToast('活动列表获取失败,请重试')
|
||||
})
|
||||
.finally(() => {
|
||||
listLoading.value = false
|
||||
listFinished.value = true
|
||||
})
|
||||
$toastText('活动列表获取失败,请重试')
|
||||
} finally {
|
||||
this.listLoading = false
|
||||
this.listFinished = true
|
||||
$toastClear()
|
||||
}
|
||||
},
|
||||
|
||||
const detectWeChatEnv = () => {
|
||||
detectWeChatEnv() {
|
||||
const userAgent = navigator.userAgent.toLowerCase()
|
||||
isWeChatEnv.value = /micromessenger/.test(userAgent)
|
||||
}
|
||||
this.isWeChatEnv = /micromessenger/.test(userAgent)
|
||||
},
|
||||
|
||||
// 选择活动:自动填充主办方
|
||||
const onSelectActivity = (item) => {
|
||||
selectedActivity.value = item
|
||||
selectedActivityTitle.value = item.title
|
||||
showActivityPicker.value = false
|
||||
generatePoster()
|
||||
}
|
||||
onSelectActivity(item) {
|
||||
this.selectedActivity = item
|
||||
this.selectedActivityTitle = item.title
|
||||
this.showActivityPicker = false
|
||||
this.generatePoster()
|
||||
},
|
||||
|
||||
const onLoadMore = () => {
|
||||
listLoading.value = false
|
||||
listFinished.value = true
|
||||
}
|
||||
onLoadMore() {
|
||||
this.listLoading = false
|
||||
this.listFinished = true
|
||||
},
|
||||
|
||||
const formatDateToShow = (timeStr) => {
|
||||
formatDateToShow(timeStr) {
|
||||
if (!timeStr) return ''
|
||||
const date = new Date(timeStr)
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
return `${year}年${month}月${day}日`
|
||||
}
|
||||
},
|
||||
|
||||
const formatDateToChinese = (timeStr) => {
|
||||
formatDateToChinese(timeStr) {
|
||||
if (!timeStr) {
|
||||
const now = new Date()
|
||||
const year = now.getFullYear()
|
||||
@ -194,37 +220,38 @@ const formatDateToChinese = (timeStr) => {
|
||||
const [datePart] = timeStr.split(' ')
|
||||
const [year, month, day] = datePart.split('-')
|
||||
return `${year}/${month}/${day}`
|
||||
}
|
||||
},
|
||||
|
||||
const formatTime = (timeStr) => {
|
||||
formatTime(timeStr) {
|
||||
if (!timeStr) return '14:00'
|
||||
const [, timePart] = timeStr.split(' ')
|
||||
return timePart.slice(0, 5)
|
||||
}
|
||||
},
|
||||
|
||||
const showImagePreviewFn = (img) => {
|
||||
return showImagePreview([img])
|
||||
}
|
||||
showImagePreviewFn(img) {
|
||||
return ImagePreview({
|
||||
images: [img],
|
||||
showIndex: true
|
||||
})
|
||||
},
|
||||
|
||||
const generatePoster = async () => {
|
||||
async generatePoster() {
|
||||
try {
|
||||
if (!selectedActivity.value) {
|
||||
showDialog({ message: '请先选择活动!' })
|
||||
if (!this.selectedActivity) {
|
||||
$toastText('请先选择活动!')
|
||||
return
|
||||
}
|
||||
this.isGenerating = true
|
||||
$toastLoading('海报生成中...')
|
||||
|
||||
isGenerating.value = true
|
||||
const toast = showLoadingToast({
|
||||
message: '海报生成中...',
|
||||
forbidClick: true,
|
||||
duration: 0
|
||||
})
|
||||
// Vue 2 中使用 $nextTick
|
||||
await this.$nextTick()
|
||||
|
||||
await nextTick()
|
||||
const posterElement = posterRef.value
|
||||
// 注意:原代码中使用了 ref="posterRef",这里通过 this.$refs 访问
|
||||
const posterElement = this.$refs.posterRef
|
||||
if (!posterElement) {
|
||||
isGenerating.value = false
|
||||
toast.close()
|
||||
this.isGenerating = false
|
||||
$toastClear()
|
||||
return
|
||||
}
|
||||
|
||||
@ -236,32 +263,56 @@ const generatePoster = async () => {
|
||||
imageTimeout: 10000
|
||||
})
|
||||
|
||||
posterImg.value = canvas.toDataURL('image/png', 1.0)
|
||||
toast.close()
|
||||
showToast({ message: '海报生成成功!', icon: 'success' })
|
||||
this.posterImg = canvas.toDataURL('image/png', 1.0)
|
||||
$toastClear()
|
||||
$toastSuccess('海报生成成功')
|
||||
} catch (err) {
|
||||
console.error('生成海报失败:', err)
|
||||
showToast({ message: '生成海报失败,请重试!', icon: 'fail' })
|
||||
$toastText('生成海报失败,请重试!')
|
||||
} finally {
|
||||
isGenerating.value = false
|
||||
}
|
||||
this.isGenerating = false
|
||||
$toastClear()
|
||||
}
|
||||
},
|
||||
|
||||
function downloadPoster() {
|
||||
if (!posterImg.value) return
|
||||
downloadPoster() {
|
||||
if (!this.posterImg) return
|
||||
const link = document.createElement('a')
|
||||
link.href = posterImg.value
|
||||
// 修复文件名括号闭合、正则多余/的问题
|
||||
const fileName = `[${selectedActivity.value?.title || '活动'}]海报.png`
|
||||
link.href = this.posterImg
|
||||
const fileName = `[${this.selectedActivity?.title || '活动'}]海报.png`
|
||||
link.download = fileName.replace(/[\\/:*?"<>|]/g, '')
|
||||
link.click()
|
||||
URL.revokeObjectURL(link.href)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听器 (替代 watch(selectedActivity, ...))
|
||||
selectedActivity: {
|
||||
handler(newVal) {
|
||||
if (newVal && newVal.id) {
|
||||
// 自动从活动数据中读取主办方
|
||||
this.sponsorName = newVal.sponsor || ''
|
||||
this.openId = localStorage.getItem('openid')
|
||||
|
||||
onMounted(() => {
|
||||
detectWeChatEnv()
|
||||
getData()
|
||||
// 注意:Vue 2 中通常通过 this.$refs 访问 DOM 元素
|
||||
const canvas = this.$refs.qrcodeCanvas
|
||||
if (canvas) {
|
||||
const link = `https://love.ufutx.cn/api/official/live/wechat/FamilyAuth?merchant_id=44&serve_tab=&from_openid=${this.openId}&url=https%3A%2F%2Flove.ufutx.cn%2Fpu%2F%23%2FactivityDetails%2F${newVal.id}`
|
||||
|
||||
QRCode.toCanvas(canvas, link, {
|
||||
width: 76,
|
||||
margin: 1,
|
||||
color: { dark: '#000000', light: '#ffffff' }
|
||||
}).catch(err => {
|
||||
console.error('生成二维码失败:', err)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
immediate: true // 如果需要立即执行一次,设置 immediate
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -538,6 +589,12 @@ img {
|
||||
color: #9ca3af;
|
||||
font-size: 14px;
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
.vant-select-icon{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 弹窗样式 */
|
||||
@ -581,6 +638,7 @@ img {
|
||||
.scroll-wrapper {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
|
||||
.activity-item {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user