Commit 5cbd6d49 authored by spc's avatar spc

gameWebview

parent da8a3215
<template>
<view class="webview-container">
<!-- Webview内容 -->
<web-view :src="webviewUrl" :key="webviewUrl" @message="getMessage" class="webview-content"></web-view>
</view>
</template>
<script setup>
import { ref, watch, nextTick } from 'vue'
import { useUserStore } from '@/stores/user.js'
import { useGlobalStore } from '../../stores/global'
import { fetchSyWebviewJSON } from '../../api/sywebview'
import { fetchGameActConfigJSON } from '../../api/home'
import { onLoad, onShow, onShareAppMessage, onShareTimeline, onPageScroll } from "@dcloudio/uni-app";
import { jump, JumpType } from '../../utils'
import md from '../../md';
// 响应式数据
const statusBarHeight = ref(0)
const webviewUrl = ref('')
const share = ref(null) // 分享数据
const pageOptions = ref({})
const registered = ref(undefined)
// 获取用户store
const userStore = useUserStore()
const globalStore = useGlobalStore()
// 检查用户是否注册
function getRegistered() {
return !!(userStore.userInfo && userStore.userInfo?.memberId !== "not_login")
}
// 处理返回逻辑
const handleBack = () => {
try {
uni.navigateBack({
delta: 1,
fail: () => {
// 如果返回失败,跳转到首页
uni.redirectTo({
url: '/pages/index/index'
})
}
})
} catch (error) {
console.log('返回失败:', error)
uni.redirectTo({
url: '/pages/index/index'
})
}
}
// 登录获取 cuk
const ensureAutoLogin = async () => {
await new Promise(resolve => {
userStore.syWxAutoLogin(resolve)
})
}
// 接收webview消息
const getMessage = (e) => {
console.log('=== Webview 消息接收开始 ===')
console.log('完整事件对象:', e)
console.log('事件详情:', e.detail)
// 尝试多种方式获取数据
let messageData = null
// 方式1:从 e.detail.data 获取
if (e.detail && e.detail.data) {
messageData = e.detail.data
console.log('从 e.detail.data 获取到数据:', messageData)
}
if (messageData) {
console.log('消息数据类型:', typeof messageData)
console.log('消息数据是否为数组:', Array.isArray(messageData))
share.value = messageData[messageData.length - 1]
}
}
let baseUrl = '' // 默认URL
// 初始化 webview URL
const initWebviewUrl = async () => {
const options = pageOptions.value
console.log('页面参数 options:', options)
// 如果没有直接传入 URL,则从接口获取游戏配置
if (!baseUrl) {
// 从接口获取游戏配置
const configRes = await fetchGameActConfigJSON()
console.log('游戏配置接口返回:', configRes)
if (configRes && configRes.data) {
// 从链接参数中获取 gameType,默认为 'lianliankan'
const gameType = options.gameType || 'lianliankan'
baseUrl = configRes.data[gameType].url
}
}
if (!baseUrl) {
uni.redirectTo({
url: '/pages/index/index'
})
return
}
// 如果 baseUrl 已经包含协议,直接使用;否则添加协议
if (!baseUrl.startsWith('http://') && !baseUrl.startsWith('https://')) {
baseUrl = 'https://' + baseUrl
}
const cuk = globalStore.cuk
const openId = globalStore.openId
const unionId = globalStore.unionId
// scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
const scene = options.scene ? decodeURIComponent(decodeURIComponent(options.scene)) : null
// 清理不需要传递给 H5 的参数
const cleanOptions = { ...options }
delete cleanOptions.scene
delete cleanOptions.url
delete cleanOptions.baseUrl
// gameType 不需要传递给 H5,因为它只是用来选择 baseUrl
delete cleanOptions.gameType
console.log("scene 参数:", scene)
console.log("清理后的 options:", cleanOptions)
console.log("原始 options:", options)
// 将 options 的所有参数原样作为查询参数传给 H5,并补齐 cuk
const params = { ...cleanOptions }
if (cuk && !params.cuk) params.cuk = cuk
// 添加用户信息参数
if (openId && !params.miniopenid) params.miniopenid = openId
if (unionId && !params.unionId) params.unionId = unionId
// 获取会员信息(优先从 memberInfo 获取,如果没有则从 userInfo 获取)
const memberInfo = userStore.memberInfo || userStore.userInfo
const babyInfo = userStore.babyInfo
// 添加微信昵称(优先使用 babyInfo.babyName,没有则使用默认值)
if (babyInfo?.babyName) {
params.wxNickName = babyInfo.babyName
} else {
params.wxNickName = '暂无昵称'
}
// 添加 memberId(如果已注册)
if (memberInfo?.memberId && memberInfo.memberId !== "not_login") {
params.crmId = memberInfo.memberId
// 添加会员ID
params.memberid = memberInfo.memberId
// 添加是否登录(1表示已登录,0表示未登录)
params.programLogin = '1'
// 添加会员等级(从 gradeList 中根据 grade 获取 gradeName)
if (memberInfo.grade !== undefined && memberInfo.grade !== null) {
// 优先从 gradeList 中查找对应的 gradeName
if (memberInfo.gradeList && Array.isArray(memberInfo.gradeList)) {
const currentGrade = String(memberInfo.grade)
const gradeItem = memberInfo.gradeList.find(item => String(item.grade) === currentGrade)
if (gradeItem && gradeItem.gradeName) {
params.memberType = gradeItem.gradeName
} else if (memberInfo.gradeName) {
// 如果 gradeList 中找不到,使用 gradeName
params.memberType = memberInfo.gradeName
} else {
// 如果都没有,使用 grade 值
params.memberType = currentGrade
}
} else if (memberInfo.gradeName) {
// 如果没有 gradeList,使用 gradeName
params.memberType = memberInfo.gradeName
} else {
// 如果都没有,使用 grade 值
params.memberType = String(memberInfo.grade)
}
}
} else {
// 未登录状态
params.programLogin = '0'
}
const paramStr = Object.keys(params)
.filter(key => params[key] !== undefined && params[key] !== null && params[key] !== '')
.map(key => `${key}=${encodeURIComponent(params[key])}`)
.join('&')
// p 渠道参数
// openId 用户openid
// unionId 用户unionid
// cuk
// shareToken 分享人token
// pt 分享海报人token
// 示例:
// https://25niansuyuan.feihe.com/projects/Firmus/dev/index?p=xmh&openId=用户openid&unionId=用户unionid&&pt=yzhd123&shareToken=yzhd123&cuk=12121
// 处理 scene 参数
if (scene) {
// 如果 scene 以 ? 开头,直接拼接
if (scene[0] === '?') {
baseUrl += scene
} else {
// 如果 scene 不以 ? 开头,需要判断 baseUrl 是否已有参数
baseUrl += baseUrl.includes('?') ? `&${scene}` : `?${scene}`
}
}
// 拼接其他参数
if (paramStr) {
// 判断 baseUrl 是否已包含查询参数
const separator = baseUrl.includes('?') ? '&' : '?'
webviewUrl.value = baseUrl + separator + paramStr
} else {
webviewUrl.value = baseUrl
}
console.log('Webview页面加载,URL:', webviewUrl.value)
console.log('参数字符串:', paramStr)
console.log('基础URL:', baseUrl)
}
// 监听注册状态变化,初始化 webview URL
watch(() => registered.value, (newVal, oldVal) => {
if (newVal && newVal !== oldVal) {
nextTick(() => {
initWebviewUrl()
})
}
})
// 页面显示时处理授权逻辑
onShow(async () => {
const oldVal = registered.value
await ensureAutoLogin()
await userStore.loadUserInfo()
// 加载会员信息以获取 grade 等详细信息
await userStore.loadMemberInfo()
registered.value = getRegistered()
if (oldVal === undefined) {
// 首次加载
// 不需要登录,直接初始化 URL
if (!webviewUrl.value) {
await initWebviewUrl()
}
} else {
// 授权状态变化:如果从已注册变为未注册(授权失败),显示提示并返回
if (registered.value === false) {
uni.showToast({
title: "授权失败,即将返回",
icon: "none",
});
setTimeout(() => {
handleBack()
}, 1000)
}
}
})
// 页面参数接收
onLoad(async (options) => {
pageOptions.value = options
console.log('页面参数:', options)
// 设置页面导航栏样式为自定义(去掉默认导航栏)
// #ifdef MP-WEIXIN
wx.setPageStyle({
style: {
navigationStyle: 'custom'
}
})
// #endif
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']// shareAppMessage表示"发送给朋友"按钮,shareTimeline表示"分享到朋友圈"按钮
})
console.warn("wx", wx.showShareMenu)
// 获取状态栏高度
const systemInfo = uni.getSystemInfoSync()
statusBarHeight.value = systemInfo.statusBarHeight || 0
})
// 分享功能
onShareAppMessage((options) => {
console.log('分享数据:', share.value)
console.log('分享选项:', options)
md.sensorLogTake({
xcxClick: "suyuan202508H5Click",
pageName: "星妈会分享页",
buttonName: "星妈会分享出",
});
if (share.value) {
const shareurl = share.value.shareUrl
const title = share.value.shareTitle
const imageUrl = share.value.shareImageUrl
console.log('使用分享数据:1', { title, shareurl, imageUrl })
return {
title: title,
path: shareurl || '/pages/index/index',
imageUrl: imageUrl || '',
success: function (res) {
console.log('分享成功:', res)
//星妈会埋点方法,用户分享成功后触发事件
},
fail: function (res) {
console.log('分享失败:', res)
},
complete: function (res) {
console.log('分享完成:', res)
}
}
}
// 如果没有分享数据,返回默认分享
return {
path: '/pages/index/index'
}
})
onShareTimeline((options) => {
console.log('分享朋友圈数据:', share.value)
md.sensorLogTake({
xcxClick: "suyuan202508H5Click",
pageName: "星妈会分享页",
buttonName: "星妈会分享出",
});
if (share.value) {
const shareurl = share.value.shareUrl
const title = share.value.shareTitle
const imageUrl = share.value.shareImageUrl
console.log('使用分享数据:', { title, shareurl, imageUrl })
return {
title: title || '分享',
path: shareurl || '/pages/gameWebview/webview',
imageUrl: imageUrl || '',
success: function (res) {
//星妈会埋点方法,用户分享成功后触发事件
console.log('分享成功:', res)
},
fail: function (res) {
console.log('分享失败:', res)
},
complete: function (res) {
console.log('分享完成:', res)
}
}
}
// 如果没有分享数据,返回默认分享
return {
path: '/pages/index/index'
}
})
</script>
<style lang="less" scoped>
.webview-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
background-color: #fff;
}
.webview-content {
flex: 1;
width: 100%;
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment